package com.erp.erp_ui.money.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.erp.enums.ModuleTypeEnum;
import com.erp.enums.OperationTypeEnum;
import com.erp.erp_entitys.User.UserEntity;
import com.erp.erp_entitys.business.entity.CarryDetailEntity;
import com.erp.erp_entitys.business.entity.CarryDetailProductEntity;
import com.erp.erp_entitys.business.req.StatisticsInfoReq;
import com.erp.erp_entitys.log.entity.DataInfoLogEntity;
import com.erp.erp_entitys.money.entity.ReceivePaymentDetailEntity;
import com.erp.erp_entitys.money.entity.ReceivePaymentEntity;
import com.erp.erp_entitys.money.entity.ReceivePaymentRefundEntity;
import com.erp.erp_entitys.money.entity.ReceivePaymentSplitEntity;
import com.erp.erp_entitys.money.req.*;
import com.erp.erp_entitys.money.rsp.*;
import com.erp.erp_entitys.warehouse.entity.AnnexEntity;
import com.erp.erp_entitys.warehouse.entity.TempAnnexEntity;
import com.erp.erp_entitys.warehouse.req.DictionaryInfoReq;
import com.erp.erp_entitys.warehouse.rsp.CompanyInfoRsp;
import com.erp.erp_entitys.warehouse.rsp.DictionaryInfoRsp;
import com.erp.erp_servers.log.IDataInfoLogService;
import com.erp.erp_servers.money.IReceivePaymentDetailService;
import com.erp.erp_servers.money.IReceivePaymentRefundService;
import com.erp.erp_servers.money.IReceivePaymentService;
import com.erp.erp_servers.money.IReceivePaymentSplitService;
import com.erp.erp_servers.warehouse.IAnnexService;
import com.erp.erp_servers.warehouse.IStockService;
import com.erp.erp_servers.warehouse.ITempAnnexService;
import com.erp.erp_ui.business.vo.DataInfoLogVo;
import com.erp.erp_ui.money.enums.MoneyOperationStatusEnum;
import com.erp.erp_ui.money.req.*;
import com.erp.erp_ui.money.vo.*;
import com.erp.erp_ui.warehouse.enums.DataIsValidEnum;
import com.erp.erp_ui.warehouse.req.AnnexReq;
import com.erp.erp_ui.warehouse.vo.*;
import com.erp.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName : ReceivePaymentService
 * @Description : 资金管理-收款业务逻辑层
 * @Author : lst
 * @Date: 2020-12-04 15:10
 */
@Service
public class ReceivePaymentService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(ReceivePaymentService.class);

    /**
     * 资金管理-收款主表接口
     */
    private final IReceivePaymentService receivePaymentService;

    /**
     * 资金管理-收款明细接口
     */
    private final IReceivePaymentDetailService receivePaymentDetailService;


    /**
     * 资金管理-收款-退款接口
     */
    private final IReceivePaymentRefundService receivePaymentRefundService;

    /**
     * 资金管理-收款-拆分接口
     */
    private final IReceivePaymentSplitService receivePaymentSplitService;

    /**
     * 库存接口
     */
    private final IStockService stockService;

    /**
     * 附件接口
     */
    private final IAnnexService annexService;

    /**
     * 临时附件接口
     */
    private final ITempAnnexService tempAnnexService;

    /**
     * 操作日志信息接口
     */
    private final IDataInfoLogService dataInfoLogService;


    public ReceivePaymentService(IReceivePaymentService receivePaymentService,
                                 IReceivePaymentDetailService receivePaymentDetailService,
                                 IReceivePaymentRefundService receivePaymentRefundService,
                                 IReceivePaymentSplitService receivePaymentSplitService,
                                 IStockService stockService,
                                 IAnnexService annexService,
                                 ITempAnnexService tempAnnexService,
                                 IDataInfoLogService dataInfoLogService) {
        this.receivePaymentService = receivePaymentService;
        this.receivePaymentDetailService = receivePaymentDetailService;
        this.receivePaymentRefundService = receivePaymentRefundService;
        this.receivePaymentSplitService = receivePaymentSplitService;
        this.stockService = stockService;
        this.annexService = annexService;
        this.tempAnnexService = tempAnnexService;
        this.dataInfoLogService = dataInfoLogService;
    }

    /**
     * 首页-获取分页信息
     *
     * @param req 查询条件
     * @return 分页结果
     */
    public PageInfo<ReceivePaymentPageListVo> getReceivePaymentListByPage(ReceivePaymentPageListReq req) {
        //初始化回参集合
        List<ReceivePaymentPageListVo> pageVos = new ArrayList<>();
        if (null == req.getStatus() || (!req.getStatus().equals(MoneyOperationStatusEnum.FIND_BOX.getId()) && !req.getStatus().equals(MoneyOperationStatusEnum.REGISTRATION_BOX.getId()))) {
            if (StringUtils.isEmpty(req.getOperationNo()) && StringUtils.isEmpty(req.getSalesmanCode()) && StringUtils.isEmpty(req.getDeptOperationCode()) && StringUtils.isEmpty(req.getDeptSalesmanCode())) {
                if (StringUtils.isEmpty(req.getIds())) {
                    //获取分页信息
                    PageInfo pageInfo = new PageInfo();
                    pageInfo.setList(pageVos);
                    return pageInfo;
                }
            }
        }
        //初始化查询条件
        ReceivePaymentListReq pageReq = new ReceivePaymentListReq();
        //赋值
        BeanUtils.copyProperties(req, pageReq);
        //调用接口获取查询结果
        List<ReceivePaymentInfoRsp> receivePaymentInfoList = receivePaymentService.getReceivePaymentInfo(pageReq);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(receivePaymentInfoList);
        if (CollectionUtils.isEmpty(receivePaymentInfoList)) {
            pageInfo.setList(pageVos);
            return pageInfo;
        }
        for (ReceivePaymentInfoRsp other : receivePaymentInfoList) {
            ReceivePaymentPageListVo pageVo = new ReceivePaymentPageListVo();
            BeanUtils.copyProperties(other, pageVo);
            //日期转换
            pageVo.setTime(DateUtils.format(other.getTime(), DateUtils.DATE_PATTERN));
            //状态转换
            pageVo.setStatusStr(MoneyOperationStatusEnum.getDescById(other.getStatus()));
            //收款账号:名称_账号
            pageVo.setAccountNo(other.getAccountName() + "_" + other.getAccountNo());
            if (null != req.getStatus()) {
                if (req.getStatus().equals(MoneyOperationStatusEnum.TO_BE_CONFIRMED_BOX.getId())) {
                    //如果查询条件为：待确认箱，则将数据状态临时修改为 待确认箱
                    pageVo.setStatus(MoneyOperationStatusEnum.TO_BE_CONFIRMED_BOX.getId());
                    pageVo.setStatusStr(MoneyOperationStatusEnum.TO_BE_CONFIRMED_BOX.getDesc());
                } else if (req.getStatus().equals(MoneyOperationStatusEnum.CONFIRMATION_BOX.getId())) {
                    //如果查询条件为：确认箱，则将数据状态临时修改为 确认箱
                    pageVo.setStatus(MoneyOperationStatusEnum.CONFIRMATION_BOX.getId());
                    pageVo.setStatusStr(MoneyOperationStatusEnum.CONFIRMATION_BOX.getDesc());
                }

            }

            pageVos.add(pageVo);
        }
        pageInfo.setList(pageVos);
        return pageInfo;
    }

    /**
     * 资金管理-收款-登记新增、修改
     *
     * @param req      新增、修改参数实体
     * @param creator  创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    @Transactional(rollbackFor = Exception.class)
    public R add(AddReceivePaymentReq req, String creator, String createNo) throws ParseException {
        boolean billNoCheckFlag = (null != req.getId() && req.getBillNo().equals(req.getNewBillNo()));
        if (!billNoCheckFlag) {
            //单号做唯一校验
            boolean billNoFlag = checkRepeatBillNo(req.getBillNo());
            if (!billNoFlag) {
                return R.buildError(ResultStatusEnum.BILL_NO_REPEAT);
            }
        }
        //主表新增、修改
        Integer id = addOrUpdate(req, creator, createNo);
        if (null == id) {
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }

        //第二步：附件新增、修改
        boolean flag = addAnnex(req.getAnnexList(), id, creator, createNo);
        if (!flag) {
            LOGGER.info("仓库管理-其它出库-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //第三步：删除临时附件信息
        deleteTempAnnex(req.getAnnexList());

        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 批量处理临时附件信息，将临时附件设置为失效
     *
     * @param annexReqs
     */
    private void deleteTempAnnex(List<AnnexReq> annexReqs) {
        //没有附件
        if (CollectionUtils.isEmpty(annexReqs)) {
            return;
        }
        //存在附件
        for (AnnexReq annex : annexReqs) {
            if (null != annex.getNews()) {
                //旧附件,不用修改
                continue;
            }
            TempAnnexEntity tempAnnex = new TempAnnexEntity();
            //设置临时附件id
            tempAnnex.setId(annex.getId());
            //设置修改时间
            tempAnnex.setUpdateTime(new Date());
            //将附件设置为失效
            tempAnnex.setValid(0);
            tempAnnexService.update(tempAnnex);
        }

    }

    /**
     * 附件新增
     *
     * @param annexReqs  附件信息
     * @param outStockId 入库id
     * @param operator   操作人
     * @param operatorNo 操作人编码
     * @return 是否新增成功(true : 成功 false : 失败)
     */
    private boolean addAnnex(List<AnnexReq> annexReqs, Integer outStockId, String operator, String operatorNo) {
        try {
            //没有附件,不新增
            if (CollectionUtils.isEmpty(annexReqs)) {
                return true;
            }
            //存在附件,新增附件信息
            List<AnnexEntity> list = new ArrayList<>();
            //获取旧的附件id集合
            List<Integer> oldIds = new ArrayList<>();
            for (AnnexReq annexReq : annexReqs) {
                if (null != annexReq.getNews()) {
                    //属于旧附件 只取id,不新增
                    oldIds.add(annexReq.getId());
                    continue;
                }
                AnnexEntity annex = new AnnexEntity();
                BeanUtils.copyProperties(annexReq, annex);
                //设置关联模块id
                annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
                //设置关联模块父id
                annex.setParentId(outStockId);
                //设置上传时间
                annex.setUploadTime(DateUtils.convertStringToDate(annexReq.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
                //设置修改时间
                annex.setUpdateTime(new Date());
                //设置操作人
                annex.setOperator(operator);
                //设置操作人编码
                annex.setOperatorNo(operatorNo);
                //设置数据有效
                annex.setValid(1);

                list.add(annex);
            }
            if (oldIds.size() > 0) {
                //通过调拨id获取修改附件信息
                AnnexEntity annex = new AnnexEntity();
                annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
                annex.setParentId(outStockId);
                //获取上次附件信息
                List<AnnexEntity> annexList = annexService.queryAll(annex);
                if (!CollectionUtils.isEmpty(annexList)) {
                    //获取上次附件id集合
                    List<Integer> oldAnnexIds = annexList.stream().map(p -> p.getId()).collect(Collectors.toList());
                    //得到被删除的附件id
                    Collection collection = new ArrayList(oldAnnexIds);
                    collection.removeAll(oldIds);
                    if (collection.size() > 0) {
                        Iterator<Integer> it = collection.iterator();
                        while (it.hasNext()) {
                            int id = it.next();
                            AnnexEntity annexEntity = new AnnexEntity();
                            annexEntity.setId(id);
                            //将被删除的附件设为失效
                            annexEntity.setValid(DataIsValidEnum.INVALID.getId());

                            annexService.update(annexEntity);
                        }
                    }
                }
            }
            if (!CollectionUtils.isEmpty(list)) {
                //附件批量新增
                int res = annexService.batchInsert(list);
                if (res == list.size()) {
                    return true;
                }
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    /**
     * 新增、修改
     *
     * @param req      参数实体
     * @param creator  创建人
     * @param createNo 创建人编码
     * @return 新增、修改结果
     */
    private Integer addOrUpdate(AddReceivePaymentReq req, String creator, String createNo) throws ParseException {
        //初始化对象
        ReceivePaymentEntity data = new ReceivePaymentEntity();
        //赋值
        BeanUtils.copyProperties(req, data);
        //收款时间
        data.setTime(DateUtils.convertStringToDate(req.getTime(), DateUtils.DATE_PATTERN));
        //设置创建人
        data.setOperator(creator);
        //设置创建人编码
        data.setOperationNo(createNo);
        //设置状态
        if (req.getSave().equals(1)) {
            //选择保存：登记箱
            data.setStatus(MoneyOperationStatusEnum.REGISTRATION_BOX.getId());
        } else if (req.getSave().equals(2)) {
            //选择保存并招领：招领箱
            data.setStatus(MoneyOperationStatusEnum.FIND_BOX.getId());
        }

        if (null == req.getId()) {
            //新增
            //创建日期
            data.setCreateDate(new Date());
            //设置有效性
            data.setValid(DataIsValidEnum.VALID.getId());
            //调用接口新增
            receivePaymentService.insert(data);
        } else {
            //修改

            //添加修改日志
            //获取修改前对象数据
            ReceivePaymentEntity oldData = receivePaymentService.queryById(req.getId());
            BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
            String info = logUtil.contrastObj(oldData, data);
            if(StringUtils.isNotEmpty(info)) {
                //新增日志信息
                DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                //模块主表id
                dataInfoLog.setParentId(req.getId());
                //模块id
                dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
                //操作人编码
                dataInfoLog.setOperationCode(createNo);
                //操作人名称
                dataInfoLog.setOperationName(creator);
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());
                //操作时间
                dataInfoLog.setOperationTime(new Date());
                //操作内容
                dataInfoLog.setOperationContent("主信息:" + info);

                dataInfoLogService.insert(dataInfoLog);
            }

            //修改时间
            data.setModifyTime(new Date());

            receivePaymentService.update(data);
        }
        return data.getId();
    }

    /**
     * 校验单号是否存在
     *
     * @param billNo 单号
     * @return true:不重复 false:重复
     */
    private boolean checkRepeatBillNo(String billNo) {
        ReceivePaymentEntity req = new ReceivePaymentEntity();
        req.setBillNo(billNo);
        List<ReceivePaymentEntity> list = receivePaymentService.queryAll(req);
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }
        return false;
    }

    /**
     * 获取币种
     *
     * @return 币种
     */
    public List<DictionaryInfoVo> getDictionaryInfo(DictionaryInfoReq dictionaryInfosReq) {
        //初始化回参
        List<DictionaryInfoVo> dictionaryVos = new ArrayList<>();
        List<DictionaryInfoRsp> dictionaryInfos = stockService.getDictionaryInfo(dictionaryInfosReq);
        if (CollectionUtils.isEmpty(dictionaryInfos)) {
            return dictionaryVos;
        }
        for (DictionaryInfoRsp infoRsp : dictionaryInfos) {
            DictionaryInfoVo vo = new DictionaryInfoVo();
            BeanUtils.copyProperties(infoRsp, vo);
            //汇率转换
            //获取汇率
            String exchangeRate = infoRsp.getExchangeRate();
            if (StringUtils.isBlank(exchangeRate)) {
                vo.setExchangeRate(new BigDecimal("0"));
            } else {
                vo.setExchangeRate(new BigDecimal(exchangeRate));
            }

            dictionaryVos.add(vo);
        }

        return dictionaryVos;
    }

    /**
     * 资金管理-收款-查看详情
     *
     * @param id   收款id
     * @param type 0:查询所有箱体数据 1:只查询确认箱数据
     * @return 对应明细数据
     */
    public ReceivePaymentDetailVo getDetailInfo(Integer id, Integer type) {
        //初始化回参实体
        ReceivePaymentDetailVo vo = new ReceivePaymentDetailVo();
        if (null == id) {
            return vo;
        }

        //第一步：获取主表信息
        ReceivePaymentEntity receivePayment = receivePaymentService.queryById(id);
        if (null == receivePayment || null == receivePayment.getId()) {
            return vo;
        }
        //赋值
        BeanUtils.copyProperties(receivePayment, vo);
        //设置创建时间
        vo.setTime(DateUtils.format(receivePayment.getTime(), DateUtils.DATE_PATTERN));

        //第二步：获取明细数据
        ReceivePaymentDetailEntity detailReq = new ReceivePaymentDetailEntity();
        //设置主表id
        detailReq.setParentId(id);
        //获取有效数据
        detailReq.setValid(DataIsValidEnum.VALID.getId());
        /*if (null != type) {
            if (1 == type) {
                //数据为已确认
                detailReq.setConfirmed(1);
            } else if (2 == type) {
                //数据为待确认
                detailReq.setConfirmed(0);
            }
        }*/
        List<ReceivePaymentDetailEntity> detailEntities = receivePaymentDetailService.queryAll(detailReq);
        if (!CollectionUtils.isEmpty(detailEntities)) {
            List<ReceivePaymentDetailInfoVo> detailList = new ArrayList<>();
            for (ReceivePaymentDetailEntity detailEntity : detailEntities) {
                ReceivePaymentDetailInfoVo detailInfoVo = new ReceivePaymentDetailInfoVo();
                //赋值
                BeanUtils.copyProperties(detailEntity, detailInfoVo);
                //时间处理
                detailInfoVo.setClaimDate(DateUtils.format(detailEntity.getClaimDate(), DateUtils.DATE_PATTERN));
                if (null == detailEntity.getConfirmed()) {
                    detailInfoVo.setConfirmed(0);
                }

                detailList.add(detailInfoVo);
            }
            vo.setDetailList(detailList);
        }

        //第三步：获取对应附件信息
        getAnnexDetail(id, vo);

        //第四步：获取对应日志信息
        DataInfoLogEntity logReq = new DataInfoLogEntity();
        //主表id
        logReq.setParentId(id);
        //模块id
        logReq.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        //查询结果
        List<DataInfoLogEntity> dataInfoLog = dataInfoLogService.queryAll(logReq);
        if(!CollectionUtils.isEmpty(dataInfoLog)){
            List<DataInfoLogVo> logVos = new ArrayList<>();
            for(DataInfoLogEntity log : dataInfoLog){
                DataInfoLogVo logVo = new DataInfoLogVo();
                //赋值
                BeanUtils.copyProperties(log, logVo);
                //日期处理
                logVo.setOperationTime(DateUtils.format(log.getOperationTime(), DateUtils.DATE_TIME_PATTERN));
                //操作类型
                logVo.setOperationType(OperationTypeEnum.getDescById(log.getOperationType()));

                logVos.add(logVo);
            }

            vo.setLogList(logVos);
        }

        return vo;
    }

    /**
     * 获取公司信息
     *
     * @return 公司信息
     */
    public List<CompanyInfoRsp> getCompanyInfo() {
        return stockService.getCompanyInfo();
    }

    /**
     * 获取银行、部门信息
     *
     * @return 银行、部门
     */
    public DepartmentAndBankVo getBankAccountInfo(String code) {
        //初始化回参实体
        DepartmentAndBankVo vo = new DepartmentAndBankVo();
        //设置银行信息
        vo.setBankAccountList(stockService.getBankInfo(code));
        //设置部门信息
        vo.setDepartmentInfoList(stockService.getDepartmentInfo(code));

        return vo;
    }

    /**
     * 资金管理-收款-获取销售合同信息
     *
     * @param req 查询参数
     * @return 销售合同信息
     */
    public PageInfo<ImportContractVo> getImportContractInfo(ImportContractReq req) {
        //初始化回参对象集合
        List<ImportContractVo> voList = new ArrayList<>();
        if (StringUtils.isEmpty(req.getContractNo())
                && StringUtils.isEmpty(req.getCustomerName())
                && StringUtils.isEmpty(req.getEndSignUp())
                && StringUtils.isEmpty(req.getSalesmanCode())
                && StringUtils.isEmpty(req.getStartSignUp())) {
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;
        }
        //初始化查询参数
        ImportContractInfoReq infoReq = new ImportContractInfoReq();
        //赋值
        BeanUtils.copyProperties(req, infoReq);
        //查询
        List<ImportContractInfRsp> infoRspList = receivePaymentService.getImportContractInfo(infoReq);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(infoRspList);
        if (CollectionUtils.isEmpty(infoRspList)) {
            pageInfo.setList(voList);
            return pageInfo;
        }
        for (ImportContractInfRsp info : infoRspList) {
            BigDecimal amountReceived = new BigDecimal("0");
            if (StringUtil.isNotEmpty(info.getAmountReceived())) {
                amountReceived = info.getAmountReceived();
            }
            if (info.getTotalContract().compareTo(amountReceived) < 1) {
                //合同总额小于等于已收款金额,不再做收款
                continue;
            }
            ImportContractVo vo = new ImportContractVo();
            BeanUtils.copyProperties(info, vo);
            //设置时间
            vo.setClaimDate(DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
            //已收款金额
            vo.setAmountReceived(amountReceived);
            //收汇金额
            vo.setCollectionAmount(amountReceived);
            //未分摊金额
            vo.setUnallocatedAmount(amountReceived);
            //认领金额
            vo.setAmountClaimed(amountReceived);
            vo.setDomesticBankCharge(new BigDecimal("0.00"));
            vo.setForeignBankDeductions(new BigDecimal("0.00"));

            voList.add(vo);
        }

        pageInfo.setList(voList);
        return pageInfo;
    }


    /**
     * 资金管理-收款-获取结汇信息
     *
     * @param req 查询参数
     * @return 结汇信息
     */
    public PageInfo<ImportExchangeInfoVo> getImportExchangeInfo(ImportExchangeReq req) {
        //初始化回参对象集合
        List<ImportExchangeInfoVo> voList = new ArrayList<>();
        if (StringUtils.isEmpty(req.getContractNo())
                && StringUtils.isEmpty(req.getCustomerName())
                && StringUtils.isEmpty(req.getInvoiceNumber())
                && StringUtils.isEmpty(req.getSalesmanCode())
                && StringUtils.isEmpty(req.getStartInvoiceDate())
                && StringUtils.isEmpty(req.getEndInvoiceDate())) {
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;
        }
        //初始化查询参数
        ImportExchangeInfoReq infoReq = new ImportExchangeInfoReq();
        //赋值
        BeanUtils.copyProperties(req, infoReq);
        //查询
        List<ImportExchangeInfoRsp> infoRspList = receivePaymentService.getImportExchangeInfo(infoReq);
        //获取分页信息
        PageInfo pageInfo = new PageInfo(infoRspList);
        if (CollectionUtils.isEmpty(infoRspList)) {
            pageInfo.setList(voList);
            return pageInfo;
        }
        for (ImportExchangeInfoRsp info : infoRspList) {
            ImportExchangeInfoVo vo = new ImportExchangeInfoVo();
            BeanUtils.copyProperties(info, vo);
            //设置时间
            vo.setClaimDate(DateUtils.format(new Date(), DateUtils.DATE_PATTERN));
            //结汇合同金额
            BigDecimal settlementAmount = new BigDecimal("0");
            if(StringUtil.isNotEmpty(info.getSettlementAmount())){
                settlementAmount = info.getSettlementAmount().setScale(2, BigDecimal.ROUND_HALF_UP);
            }
            vo.setSettlementAmount(settlementAmount);
            //设置合同未收款金额 = 合同总额 - 合同已收款金额
            //已收款金额
            BigDecimal amountReceived = new BigDecimal("0");
            if (StringUtil.isNotEmpty(info.getContractAmountReceived())) {
                amountReceived = info.getContractAmountReceived();
            }
            //合同总额
            BigDecimal totalContract = new BigDecimal("0");
            if (StringUtil.isNotEmpty(info.getTotalContract())) {
                totalContract = info.getTotalContract();
            }
            vo.setOutstandingAmountContract(totalContract.subtract(amountReceived));
            //已拆分金额
            BigDecimal amountSplit = new BigDecimal("0");
            if (StringUtil.isNotEmpty(info.getAmountSplit())) {
                amountSplit = info.getAmountSplit();
            }
            //结汇合同未收金额 = 结汇合同金额 - 已拆分金额
            BigDecimal money = info.getSettlementAmount().subtract(amountSplit);

            //发票总金额
            BigDecimal totalInvoice = new BigDecimal("0");
            if (StringUtil.isNotEmpty(info.getTotalInvoice())) {
                totalInvoice = info.getTotalInvoice();
            }
            //合同未收款金额=发票总金额-已收款金额
            BigDecimal outstandingAmountContract = totalInvoice.subtract(amountReceived);
            if (outstandingAmountContract.compareTo(BigDecimal.ZERO) == 0) {
                continue;
            }
            //收汇金额=结汇合同未收金额=认领金额
            vo.setCollectionAmount(money.setScale(2, BigDecimal.ROUND_HALF_UP));
            vo.setAmountClaimed(money);
            vo.setOutstandingAmountContract(outstandingAmountContract);
            vo.setAmountSplit(amountSplit);
            vo.setContractAmountReceived(amountReceived);
            vo.setContractUnclaimedAmount(money);
            vo.setUnallocatedAmount(new BigDecimal("0.00"));
            vo.setDomesticBankCharge(new BigDecimal("0.00"));
            vo.setForeignBankDeductions(new BigDecimal("0.00"));

            voList.add(vo);
        }

        pageInfo.setList(voList);
        return pageInfo;
    }

    /**
     * 获取收款类型
     *
     * @return 收款类型
     */
    public List<DictionaryInfoVo> getReceivePaymentTypeInfo(DictionaryInfoReq dictionaryInfosReq) {
        //初始化回参
        List<DictionaryInfoVo> dictionaryVos = new ArrayList<>();
        List<DictionaryInfoRsp> dictionaryInfos = stockService.getDictionaryInfo(dictionaryInfosReq);
        if (CollectionUtils.isEmpty(dictionaryInfos)) {
            return dictionaryVos;
        }
        for (DictionaryInfoRsp infoRsp : dictionaryInfos) {
            DictionaryInfoVo vo = new DictionaryInfoVo();
            BeanUtils.copyProperties(infoRsp, vo);

            dictionaryVos.add(vo);
        }

        return dictionaryVos;
    }

    /**
     * 校验主表收汇金额是否等于明细收汇金额合计 true:相等 false:不相等
     * @param req 入参实体
     * @return 主表收汇金额是否等于明细收汇金额合计 true:相等 false:不相等
     */
    private boolean checkCollectionAmountIsEqual(CollectionClaimAddReq req) {
        //主表收汇金额
        BigDecimal collectionAmount = req.getCollectionAmount();
        if (CollectionUtils.isEmpty(req.getDetailList())) {
            return false;
        }
        BigDecimal detailCollectionAmountSun = new BigDecimal("0");
        for (ReceivePaymentDetailAddReq detail : req.getDetailList()) {
            //明细收汇金额
            BigDecimal amount = detail.getCollectionAmount();
            detailCollectionAmountSun = detailCollectionAmountSun.add(amount);
        }
        if (collectionAmount.compareTo(detailCollectionAmountSun.setScale(2, BigDecimal.ROUND_HALF_UP)) == 0) {
            return true;
        }
        return false;
    }

    /**
     * 收款认领新增
     *
     * @param req 新增参数
     * @return 新增结果
     */
    public R collectionClaimAdd(CollectionClaimAddReq req, String creator, String createNo) throws ParseException {
        if (null == req.getId()) {
            LOGGER.info("资金管理-收款-收款认领新增-id为空");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        /*//第一步: 数据校验，合同认领总额不能大于合同总额
        if (!checkAmount(req.getDetailList())) {
            return R.buildError(ResultStatusEnum.RECEIVE_PAYMENT_AMOUNT_ERROR);
        }*/
        //第二步: 数据计算，主表银行扣费(本)、已认领修改
        //Map<String, BigDecimal> map = getSumAmountMap(req.getDetailList());
        //校验主表 主表收汇金额必须等于明细收汇金额总和
        /*if(!checkCollectionAmountIsEqual(req)){
            return R.buildError(ResultStatusEnum.RECEIVE_PAYMENT_COLLECTION_AMOUNT_ERROR);
        }*/
        //更新主表 银行扣费(本)、已认领金额
        ReceivePaymentEntity paymentEntity = new ReceivePaymentEntity();
        //设置主键
        paymentEntity.setId(req.getId());
        //收汇金额
        paymentEntity.setCollectionAmount(req.getCollectionAmount());
        //银行扣费(外)
        paymentEntity.setBankDeductionExcept(req.getBankDeductionExcept());
        //银行扣费(本)
        paymentEntity.setBankDeductionCapital(req.getBankDeductionCapital());
        //已认领金额
        paymentEntity.setClaimed(req.getClaimed());
        //待认领金额
        BigDecimal toBeClaimed = req.getToBeClaimed();
        paymentEntity.setToBeClaimed(toBeClaimed);
        //当待认领金额小于零时,该单据不能保存
        if (toBeClaimed.compareTo(BigDecimal.ZERO) == -1) {
            return R.buildError(ResultStatusEnum.RECEIVE_PAYMENT_AMOUNT_ERROR_MSG);
        }
        //当待认领金额为零时,单据类型为待确认箱
        boolean isZeroFlag = toBeClaimed.compareTo(BigDecimal.ZERO) == 0;
        if (isZeroFlag) {
            paymentEntity.setStatus(MoneyOperationStatusEnum.TO_BE_CONFIRMED_BOX.getId());
        }
        //更新主表数据
        receivePaymentService.update(paymentEntity);
        //添加修改日志
        //获取修改前对象数据
        ReceivePaymentEntity oldData = receivePaymentService.queryById(req.getId());
        BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
        String info = logUtil.contrastObj(oldData, paymentEntity);
        if(StringUtils.isNotEmpty(info)) {
            //新增日志信息
            DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
            //模块主表id
            dataInfoLog.setParentId(req.getId());
            //模块id
            dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
            //操作人编码
            dataInfoLog.setOperationCode(createNo);
            //操作人名称
            dataInfoLog.setOperationName(creator);
            //操作类型
            dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());
            //操作时间
            dataInfoLog.setOperationTime(new Date());
            //操作内容
            dataInfoLog.setOperationContent("主信息:" + info);

            dataInfoLogService.insert(dataInfoLog);
        }

        //第三步: 明细数据新增
        insertDetail(req, req.getId(), creator, createNo);

        //第四步: 添加附件信息
        boolean flag = addAnnex(req.getAnnexList(), req.getId(), creator, createNo);
        if (!flag) {
            LOGGER.info("资金管理-收款-批量新增附件异常");
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        //删除临时附件信息
        deleteTempAnnex(req.getAnnexList());
        return R.build(ResultStatusEnum.SUCCESS);
    }


    /**
     * 明细新增
     *
     * @param req 入参
     * @param id  出库id
     */
    public void insertDetail(CollectionClaimAddReq req, Integer id, String creator, String createNo) throws ParseException {
        if (!CollectionUtils.isEmpty(req.getDetailList())) {
            //新增明细集合
            List<ReceivePaymentDetailEntity> addDetails = new ArrayList<>();
            for (ReceivePaymentDetailAddReq detailReq : req.getDetailList()) {
                //如果存在已确认数据,则直接跳过
                if (null != detailReq.getConfirmed() && 1 == detailReq.getConfirmed()) {
                    continue;
                }
                //资源样品明细对象
                ReceivePaymentDetailEntity detail = new ReceivePaymentDetailEntity();
                //赋值
                BeanUtils.copyProperties(detailReq, detail);
                //设置id
                detail.setParentId(id);
                //设置数据有效性(0:无效 1:有效)
                detail.setValid(DataIsValidEnum.VALID.getId());
                //日期转换
                if (StringUtils.isEmpty(detailReq.getClaimDate())) {
                    detail.setClaimDate(new Date());
                } else {
                    detail.setClaimDate(DateUtils.convertStringToDate(detailReq.getClaimDate(), DateUtils.DATE_PATTERN));
                }

                if (null == detailReq.getId()) {
                    //新增
                    if (req.getId() != null) {
                        //表明修改新增产品
                        //新增日志信息
                        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                        //模块主表id
                        dataInfoLog.setParentId(id);
                        //模块id
                        dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
                        //操作人编码
                        dataInfoLog.setOperationCode(createNo);
                        //操作人名称
                        dataInfoLog.setOperationName(creator);
                        //操作类型
                        dataInfoLog.setOperationType(OperationTypeEnum.INSERT_DATA.getId());
                        //操作时间
                        dataInfoLog.setOperationTime(new Date());
                        //操作内容
                        dataInfoLog.setOperationContent("明细信息:" + "合同编号:" + detail.getContractNo() + ",发票编号:" + detail.getInvoiceNumber());

                        dataInfoLogService.insert(dataInfoLog);
                    }
                    //创建时间
                    detail.setCreateDate(new Date());
                    //数据默认待确认
                    detail.setConfirmed(0);

                    addDetails.add(detail);
                } else {
                    //修改

                    //添加修改日志
                    //获取修改前对象数据
                    ReceivePaymentDetailEntity oldData = receivePaymentDetailService.queryById(detailReq.getId());
                    BeanChangeLogUtil logUtil = new BeanChangeLogUtil();
                    String info = logUtil.contrastObj(oldData, detail);
                    if(StringUtils.isNotEmpty(info)){
                        //新增日志信息
                        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
                        //模块主表id
                        dataInfoLog.setParentId(id);
                        //模块id
                        dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
                        //操作人编码
                        dataInfoLog.setOperationCode(createNo);
                        //操作人名称
                        dataInfoLog.setOperationName(creator);
                        //操作类型
                        dataInfoLog.setOperationType(OperationTypeEnum.UPDATE_DATA.getId());
                        //操作时间
                        dataInfoLog.setOperationTime(new Date());
                        //操作内容
                        dataInfoLog.setOperationContent("明细信息:" + info);

                        dataInfoLogService.insert(dataInfoLog);
                    }
                    detail.setModifyTime(new Date());
                    receivePaymentDetailService.update(detail);
                }

            }
            if (!CollectionUtils.isEmpty(addDetails)) {
                //调用接口保存明细数据
                receivePaymentDetailService.addList(addDetails);
            }

        }
        //处理被删除的明细
        handleBeenDeletedTransferDetail(req, creator, createNo);
    }

    /**
     * 处理被删除的明细
     *
     * @param req 明细
     */
    private void handleBeenDeletedTransferDetail(CollectionClaimAddReq req, String creator, String createNo) {
        if (CollectionUtils.isEmpty(req.getDeleteIds())) {
            return;
        }
        for (Integer deleteId : req.getDeleteIds()) {
            //添加日志
            ReceivePaymentDetailEntity detailEntity = receivePaymentDetailService.queryById(deleteId);
            //新增日志信息
            DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
            //模块主表id
            dataInfoLog.setParentId(detailEntity.getParentId());
            //模块id
            dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
            //操作人编码
            dataInfoLog.setOperationCode(createNo);
            //操作人名称
            dataInfoLog.setOperationName(creator);
            //操作类型
            dataInfoLog.setOperationType(OperationTypeEnum.DELETE_DATA.getId());
            //操作时间
            dataInfoLog.setOperationTime(new Date());
            //操作内容
            dataInfoLog.setOperationContent("明细信息:" + "合同编号:" + detailEntity.getContractNo() + ",发票编号:" + detailEntity.getInvoiceNumber());
            dataInfoLogService.insert(dataInfoLog);

            //初始化参数
            ReceivePaymentDetailEntity updateReq = new ReceivePaymentDetailEntity();
            //删除，直接将数据设为无效
            updateReq.setId(deleteId);
            //删除时间
            updateReq.setModifyTime(new Date());
            //将数据设为无效
            updateReq.setValid(DataIsValidEnum.INVALID.getId());

            //调用接口修改
            receivePaymentDetailService.update(updateReq);
        }
    }


    /**
     * 获取主表银行扣费(本),已认领金额
     *
     * @param detailList 明细数据集合
     * @return 银行扣费(本), 已认领金额
     */
    private Map<String, BigDecimal> getSumAmountMap(List<ReceivePaymentDetailAddReq> detailList) {
        Map<String, BigDecimal> map = new HashMap<>(3);
        //银行扣费(本)= 明细表中 国内银行扣费总和
        BigDecimal bankDeductionCapital = new BigDecimal("0");
        //已认领金额 = 明细中 认领金额总和
        BigDecimal claimed = new BigDecimal("0");
        for (ReceivePaymentDetailAddReq detailAddReq : detailList) {
            if (StringUtil.isNotEmpty(detailAddReq.getDomesticBankCharge())) {
                bankDeductionCapital = bankDeductionCapital.add(detailAddReq.getDomesticBankCharge());
            }
            //收汇金额
            BigDecimal collectionAmount = new BigDecimal("0");
            if (StringUtil.isNotEmpty(detailAddReq.getCollectionAmount())) {
                collectionAmount = detailAddReq.getCollectionAmount();
            }
            //国外银行扣费
            BigDecimal foreignBankDeductions = new BigDecimal("0");
            if (StringUtil.isNotEmpty(detailAddReq.getForeignBankDeductions())) {
                foreignBankDeductions = detailAddReq.getForeignBankDeductions();
            }
            //认领金额 = 收汇金额-国外银行扣费
            BigDecimal amountClaimed = collectionAmount.subtract(foreignBankDeductions);
            claimed = claimed.add(amountClaimed);
        }
        map.put("bankDeductionCapital", bankDeductionCapital);
        map.put("claimed", claimed);
        return map;
    }


    /**
     * 合同认领总额不能大于合同总额
     *
     * @param detailList 数据集合
     * @return true:校验通过 false:校验不通过
     */
    private boolean checkAmount(List<ReceivePaymentDetailAddReq> detailList) {
        if (CollectionUtils.isEmpty(detailList)) {
            return true;
        }
        //合同认领总额
        Map<String, BigDecimal> map = new HashMap<>();
        //合同总额
        Map<String, BigDecimal> totalContractMap = new HashMap<>();
        for (ReceivePaymentDetailAddReq detailAddReq : detailList) {
            //只针对发票号为空的情况(登记预收款)
            if (StringUtils.isNotBlank(detailAddReq.getInvoiceNumber())) {
                continue;
            }
            //合同号
            String contractNo = detailAddReq.getContractNo();
            //认领金额
            BigDecimal amountClaimed = new BigDecimal("0");
            if (StringUtil.isNotEmpty(detailAddReq.getAmountClaimed())) {
                amountClaimed = detailAddReq.getAmountClaimed();
            }
            if (map.containsKey(contractNo)) {
                //合同号已存在,同一合同认领金额累加
                BigDecimal newAmountClaimed = map.get(contractNo).add(amountClaimed);
                //更新数据
                map.put(contractNo, newAmountClaimed);
            } else {
                //不存在合同号,直接赋值
                map.put(contractNo, amountClaimed);
                //获取合同总额
                totalContractMap.put(contractNo, detailAddReq.getTotalContract());
            }
        }
        if (map.isEmpty()) {
            return true;
        }
        for (Map.Entry<String, BigDecimal> entry : map.entrySet()) {
            //合同认领总额
            BigDecimal amountClaimedSum = entry.getValue();
            //合同总额
            BigDecimal totalContract = totalContractMap.get(entry.getKey());
            boolean flag = amountClaimedSum.compareTo(totalContract) < 1;
            if (!flag) {
                return false;
            }
        }
        return true;
    }


    /**
     * 删除
     *
     * @param req
     */
    public void delete(OperationReq req) {
        if (null == req.getId() || null == req.getStatus()) {
            return;
        }
        deleteReceivePayment(req.getId(), req.getStatus());
    }


    /**
     * 数据更新为已确认
     *
     * @param ids 需确认的明细id集合
     */
    public void addConfirmedStatus(String ids, String id, UserEntity user) {
        if (StringUtils.isEmpty(id) || StringUtils.isBlank(ids)) {
            return;
        }
        ReceivePaymentDetailEntity detailEntityReq = new ReceivePaymentDetailEntity();
        detailEntityReq.setParentId(Integer.parseInt(id));
        detailEntityReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentDetailEntity> detailEntityList = receivePaymentDetailService.queryAll(detailEntityReq);
        if (CollectionUtils.isEmpty(detailEntityList)) {
            return;
        }
        //新增日志信息
        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
        //模块主表id
        dataInfoLog.setParentId(Integer.parseInt(id));
        //模块id
        dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        //操作人编码
        dataInfoLog.setOperationCode(user.getCode());
        //操作人名称
        dataInfoLog.setOperationName(user.getName());
        //操作时间
        dataInfoLog.setOperationTime(new Date());
        //操作类型
        dataInfoLog.setOperationType(OperationTypeEnum.CLAIM_CONFIRMATION.getId());

        StringBuilder operationContent = new StringBuilder();
        operationContent.append("单据操作:");

        for (ReceivePaymentDetailEntity detail : detailEntityList) {
            detail.setConfirmed(0);
            detail.setModifyTime(new Date());
            receivePaymentDetailService.update(detail);

            if(ids.contains(detail.getId().toString())){
                //操作合同号
                operationContent.append(detail.getContractNo() + ",");
            }
        }
        //操作内容
        dataInfoLog.setOperationContent(operationContent.toString());
        dataInfoLogService.insert(dataInfoLog);

        //存在多个id
        List<String> newIds = Arrays.asList(ids.split(","));
        for (String cid : newIds) {
            ReceivePaymentDetailEntity detailEntity = new ReceivePaymentDetailEntity();
            //设置修改id
            detailEntity.setId(Integer.parseInt(cid));
            //数据修改为已确认
            detailEntity.setConfirmed(1);
            detailEntity.setModifyTime(new Date());

            //更新数据
            receivePaymentDetailService.update(detailEntity);
        }

        //如果明细没有未确认数据,则该单据自动进确认箱
        ReceivePaymentDetailEntity detailReq = new ReceivePaymentDetailEntity();
        detailReq.setParentId(Integer.parseInt(id));
        detailReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentDetailEntity> detailEntities = receivePaymentDetailService.queryAll(detailReq);
        if (CollectionUtils.isEmpty(detailEntities)) {
            return;
        }

        for (ReceivePaymentDetailEntity detail : detailEntities) {
            if (null == detail.getConfirmed() || 0 == detail.getConfirmed()) {
                //存在待确认数据
                return;
            }
        }

        //所有数据都确认,单据自动进入确认箱
        ReceivePaymentEntity updateReq = new ReceivePaymentEntity();
        updateReq.setId(Integer.parseInt(id));
        updateReq.setModifyTime(new Date());
        updateReq.setStatus(MoneyOperationStatusEnum.CONFIRMATION_BOX.getId());
        receivePaymentService.update(updateReq);
    }


    /**
     * 资源管理-收款-一键拆分-获取拆分数据
     *
     * @param id 待拆分主表数据id
     * @return 数据
     */
    public List<SplitInfoVo> getSplitData(String id) {
        //初始化回参对象集合
        List<SplitInfoVo> voList = new ArrayList<>();
        if (StringUtils.isBlank(id)) {
            return voList;
        }
        //存在多个id
        List<String> ids = Arrays.asList(id.split(","));
        //获取拆分信息
        List<SplitInfoRsp> splitInfoRspList = receivePaymentService.getSplitInfo(ids);
        if (CollectionUtils.isEmpty(splitInfoRspList)) {
            return voList;
        }
        for (SplitInfoRsp info : splitInfoRspList) {
            SplitInfoVo vo = new SplitInfoVo();
            //赋值
            BeanUtils.copyProperties(info, vo);
            //日期处理
            vo.setTime(DateUtils.format(info.getTime(), DateUtils.DATE_PATTERN));
            //获取明细数据
            List<SplitDetailInfoRsp> detailList = info.getDetailList();
            //已拆分金额 = 对应明细 已分摊金额总和
            BigDecimal splitCompletedAmount = new BigDecimal("0");
            //未拆分金额 = 对应明细 未分摊金额总和
            BigDecimal undividedAmount = new BigDecimal("0");
            List<SplitDetailInfoVo> detailVos = new ArrayList<>();
            for (SplitDetailInfoRsp detail : detailList) {
                if (StringUtil.isNotEmpty(detail.getAllocatedAmount())) {
                    //已分摊金额累加
                    splitCompletedAmount = splitCompletedAmount.add(detail.getAllocatedAmount());
                }
                if (StringUtil.isNotEmpty(detail.getUnallocatedAmount())) {
                    //未分摊金额累加
                    undividedAmount = undividedAmount.add(detail.getUnallocatedAmount());
                }
                List<BillExchangeAndCostInfoRsp> billExchangeInfo = receivePaymentService.getBillExchangeInfoByContractNo(detail.getContractNo());
                if (CollectionUtils.isEmpty(billExchangeInfo)) {
                    continue;
                }
                //已拆分金额
                BigDecimal tmpAllocatedAmount = new BigDecimal("0");
                for (BillExchangeAndCostInfoRsp cost : billExchangeInfo) {
                    SplitDetailInfoVo detailVo = new SplitDetailInfoVo();
                    //对象赋值
                    BeanUtils.copyProperties(detail, detailVo);
                    //设置结汇id
                    detailVo.setBillId(cost.getId());
                    //金额小计合计
                    BigDecimal subTotalAmount = new BigDecimal("0");
                    if (StringUtil.isNotEmpty(cost.getSubTotalAmount())) {
                        subTotalAmount = cost.getSubTotalAmount();
                    }

                    //费用合计
                    BigDecimal costMoney = new BigDecimal("0");
                    if (StringUtil.isNotEmpty(cost.getCostMoney())) {
                        costMoney = cost.getCostMoney();
                    }

                    //合计
                    BigDecimal sum = subTotalAmount.add(costMoney);

                    //获取已分摊金额
                    BigDecimal allocatedAmount = receivePaymentService.getCollectionAmountSum(cost.getInvoiceNo(), detail.getContractNo());
                    //发票未收金额 = 合计 - 获取已分摊金额
                    BigDecimal invoiceRemainingUncollected = sum.subtract(allocatedAmount);
                    detailVo.setInvoiceRemainingUncollected(invoiceRemainingUncollected);

                    //本次拆分金额
                    BigDecimal splitAmount = new BigDecimal("0");
                    //设置结汇发票编号
                    detailVo.setInvoiceNumber(cost.getInvoiceNo());
                    BigDecimal tmpAmount = detail.getCollectionAmount().subtract(tmpAllocatedAmount);
                    if (StringUtils.isEmpty(detail.getInvoiceNumber())) {
                        //结汇单号不在收款明细中,则拆分金额取 合计后的金额与sum(收汇金额)中最小的值
                        if (tmpAmount.compareTo(sum) == 1) {
                            splitAmount = sum;
                        } else {
                            splitAmount = tmpAmount;
                        }
                    } else {
                        //合计-sum(收汇金额)结果小于等于零,不拆分,大于零拆分结果等于差值
                        BigDecimal amount = sum.subtract(tmpAmount);
                        if (amount.compareTo(BigDecimal.ZERO) < 1) {
                            continue;
                        } else {
                            splitAmount = amount;
                        }
                    }
                    //获取拆分信息
                    ReceivePaymentSplitEntity splitQuery = new ReceivePaymentSplitEntity();
                    //明细id
                    splitQuery.setDetailId(detail.getDetailId());
                    //数据有效
                    splitQuery.setValid(DataIsValidEnum.VALID.getId());
                    List<ReceivePaymentSplitEntity> splitList = receivePaymentSplitService.queryAll(splitQuery);
                    //国外银行扣费是否已被拆分 false:否 true:是
                    boolean flag = false;
                    if(!CollectionUtils.isEmpty(splitList)){
                        for(ReceivePaymentSplitEntity split : splitList){
                            if(StringUtil.isNotEmpty(split.getForeignBankDeductions()) && split.getForeignBankDeductions().compareTo(BigDecimal.ZERO) > 0){
                                //国外银行扣费大于零,表明已被拆分,不需再次拆分
                                flag = true;
                                break;
                            }
                        }
                    }
                    if(tmpAllocatedAmount.compareTo(BigDecimal.ZERO) > 0 || flag){
                        //已拆金额大于零,表明已做过拆分,国外银行扣费已默认拆给第一条明细,后续不再拆分
                        detailVo.setForeignBankDeductions(new BigDecimal("0"));
                    }
                    //国内银行扣费默认为零
                    detailVo.setDomesticBankCharge(new BigDecimal("0"));
                    //未分摊金额
                    BigDecimal unallocatedAmount = new BigDecimal("0");
                    if (StringUtil.isNotEmpty(detailVo.getUnallocatedAmount())) {
                        unallocatedAmount = detailVo.getUnallocatedAmount();
                    }
                    BigDecimal newSplitAmount = new BigDecimal("0");
                    if (splitAmount.compareTo(unallocatedAmount) == -1) {
                        //本次拆分金额小于未分摊金额
                        newSplitAmount = splitAmount;
                    } else {
                        newSplitAmount = unallocatedAmount;
                    }
                    BigDecimal tmpSplitAmount = new BigDecimal("0");
                    if(newSplitAmount.compareTo(invoiceRemainingUncollected) == -1){
                        //本次拆分金额小于发票未收金额
                        tmpSplitAmount = newSplitAmount;
                    }else {
                        tmpSplitAmount = invoiceRemainingUncollected;
                    }
                    //本次拆分金额
                    detailVo.setSplitAmount(tmpSplitAmount);
                    tmpAllocatedAmount = tmpAllocatedAmount.add(tmpSplitAmount);
                    if(tmpAllocatedAmount.compareTo(unallocatedAmount) > 0){
                        detailVo.setSplitAmount(new BigDecimal("0"));
                    }
                    detailVos.add(detailVo);
                }

                vo.setDetailList(detailVos);
            }
            vo.setSplitCompletedAmount(splitCompletedAmount);
            vo.setUndividedAmount(undividedAmount);

            voList.add(vo);
        }

        return voList;
    }


    /**
     * 一键拆分新增
     *
     * @param reqList 新增参数
     */
    public void addSplitInfo(List<SplitInfoReq> reqList) {
        if (null == reqList) {
            return;
        }
        for (SplitInfoReq splitInfoReq : reqList) {
            //获取明细数据
            List<SplitDetailInfoReq> detailList = splitInfoReq.getDetailList();
            if (CollectionUtils.isEmpty(detailList)) {
                continue;
            }
            //初始化拆分明细集合
            List<ReceivePaymentSplitEntity> splitList = new ArrayList<>();
            for (SplitDetailInfoReq detailInfoReq : detailList) {
                //合同编号
                String contractNo = detailInfoReq.getContractNo();
                //通过合同号获取结汇信息
                List<BillExchangeInfoRsp> billExchangeInfoList = receivePaymentService.getBillExchangeInfo(contractNo);
                if (CollectionUtils.isEmpty(billExchangeInfoList)) {
                    continue;
                }
                if (!StringUtil.isNotEmpty(detailInfoReq.getUnallocatedAmount())) {
                    continue;
                }
                //获取未分摊金额(本次需要拆分的金额)
                BigDecimal unallocatedAmount = detailInfoReq.getUnallocatedAmount();
                while (unallocatedAmount.compareTo(BigDecimal.ZERO) > 0) {
                    if (billExchangeInfoList.size() == 0) {
                        //拆分结束
                        break;
                    }
                    //根据未分摊金额获取需要先拆哪一条
                    BillExchangeInfoRsp billExchange = getBillExchangeInfo(unallocatedAmount, billExchangeInfoList);
                    //金额小计
                    BigDecimal moneySubtotal = billExchange.getMoneySubtotal();
                    //已拆分金额
                    BigDecimal amountSplit = new BigDecimal("0");
                    if (StringUtil.isNotEmpty(billExchange.getAmountSplit())) {
                        amountSplit = billExchange.getAmountSplit();
                    }
                    //本条数据未分摊金额 = 金额小计 - 已拆分金额
                    BigDecimal newAmount = moneySubtotal.subtract(amountSplit);

                    BillExchangeDetailReq updateReq = new BillExchangeDetailReq();
                    //设置修改id
                    updateReq.setId(billExchange.getDetailId());

                    //拆分明细新增
                    ReceivePaymentSplitEntity paymentSplit = new ReceivePaymentSplitEntity();
                    //赋值
                    BeanUtils.copyProperties(detailInfoReq, paymentSplit);
                    //设置结汇发票
                    paymentSplit.setInvoiceNumber(billExchange.getInvoiceNumber());
                    if (unallocatedAmount.compareTo(newAmount) == 1) {
                        //本次该合同未分摊金额大于结汇明细中合同未拆分金额,本次明细需要拆分的金额 = 本条数据未分摊金额,同时更新已拆分金额
                        //更新已拆分金额
                        updateReq.setAmountSplit(moneySubtotal);

                        //设置拆分明细中的拆分金额 = 本条数据未分摊金额
                        paymentSplit.setSplitAmount(newAmount);

                        //新的未分摊金额 = 未分摊金额(本次需要拆分的金额) - 本条明细拆分金额
                        unallocatedAmount = unallocatedAmount.subtract(newAmount);
                    } else {
                        //本次该合同未分摊金额小于等于结汇明细中合同未拆分金额,本次明细需要拆分的金额 = 本次该合同未分摊金额,同时更新已拆分金额
                        //新的已拆分金额 = 老的已拆分金额 + 本次该合同未分摊金额
                        BigDecimal newAmountSplit = amountSplit.add(unallocatedAmount);
                        //更新明细已拆分金额
                        updateReq.setAmountSplit(newAmountSplit);

                        //设置拆分明细中的拆分金额 = 本次该合同未分摊金额
                        paymentSplit.setSplitAmount(unallocatedAmount);

                        //新的未分摊金额为零
                        unallocatedAmount = new BigDecimal("0");
                    }
                    //创建时间
                    paymentSplit.setCreateDate(new Date());
                    //数据设为有效
                    paymentSplit.setValid(DataIsValidEnum.VALID.getId());
                    splitList.add(paymentSplit);

                    //更新结汇明细已拆分金额
                    receivePaymentService.updateBillExchangeDetail(updateReq);

                    //将该条已处理过的结汇明细在集合中删除,以便处理剩余未处理的明细
                    for (BillExchangeInfoRsp info : billExchangeInfoList) {
                        if (info.getDetailId().equals(billExchange.getDetailId())) {
                            billExchangeInfoList.remove(info);
                            break;
                        }
                    }
                }

                //拆分完成,获取本次拆分金额 = 原始未分摊金额 - 当前未分摊金额
                BigDecimal splitAmount = detailInfoReq.getUnallocatedAmount().subtract(unallocatedAmount);
                //更新收款明细表中的已分摊金额、未分摊金额
                ReceivePaymentDetailEntity detailEntityReq = new ReceivePaymentDetailEntity();
                //主键id
                detailEntityReq.setId(detailInfoReq.getDetailId());
                //已分摊金额(需累加) = 本次已拆分金额+老的已拆分金额
                BigDecimal newAllocatedAmount = new BigDecimal("0");
                if (StringUtil.isNotEmpty(detailInfoReq.getAllocatedAmount())) {
                    newAllocatedAmount = detailInfoReq.getAllocatedAmount();
                }
                detailEntityReq.setAllocatedAmount(splitAmount.add(newAllocatedAmount));
                //未分摊金额
                detailEntityReq.setUnallocatedAmount(splitAmount);
                detailEntityReq.setModifyTime(new Date());

                receivePaymentDetailService.update(detailEntityReq);
            }

            if (splitList.size() > 0) {
                //存在明细对象,新增
                receivePaymentSplitService.addList(splitList);
            }

        }

    }


    /**
     * 通过未分摊金额获取应该给哪一条结汇明细进行拆分
     *
     * @param unallocatedAmount    未分摊金额
     * @param billExchangeInfoList 结汇信息集合
     * @return 离未分摊金额最近的一条未拆分金额明细对象
     */
    private BillExchangeInfoRsp getBillExchangeInfo(BigDecimal unallocatedAmount, List<BillExchangeInfoRsp> billExchangeInfoList) {
        if (!StringUtil.isNotEmpty(unallocatedAmount)) {
            return null;
        }
        if (CollectionUtils.isEmpty(billExchangeInfoList)) {
            return null;
        }
        List<BigDecimal> list = new ArrayList<>();
        Map<BigDecimal, BillExchangeInfoRsp> map = new HashMap<>();
        for (BillExchangeInfoRsp infoRsp : billExchangeInfoList) {
            if (!StringUtil.isNotEmpty(infoRsp.getMoneySubtotal())) {
                //金额小计为空或者等于零,本次不拆分
                continue;
            }
            //已拆分金额
            BigDecimal amountSplit = new BigDecimal("0");
            if (StringUtil.isNotEmpty(infoRsp.getAmountSplit())) {
                amountSplit = infoRsp.getAmountSplit();
            }
            //本条数据未分摊金额 = 金额小计 - 已拆分金额
            BigDecimal newAmount = infoRsp.getMoneySubtotal().subtract(amountSplit);
            if (map.containsKey(newAmount)) {
                continue;
            } else {
                map.put(newAmount, infoRsp);
                list.add(newAmount);
            }

        }
        if (list.size() == 0) {
            return null;
        }
        //需要将BigDecimal类型转换为float类型
        Float[] array = list.toArray(new Float[list.size()]);
        //获取离目标数组最近的一个元素值
        float amount = getBinarySearch(array, unallocatedAmount.floatValue());

        return map.get(amount);
    }

    /**
     * 根据输入的目标数值返回离数组元素中最近的一个元素
     *
     * @param array  需要查询的数组元素
     * @param target 输入的目标数值
     * @return 在数组元素中最近的一个元素
     */
    private float getBinarySearch(Float[] array, Float target) {
        if (array.length == 1) {
            return array[0];
        }
        //重排序
        Arrays.sort(array);
        //获取结果索引
        int index = Arrays.binarySearch(array, target);
        if (index >= 0) {
            //搜索值是数组元素,从0开始计数,得搜索值的索引值,可直接根据索引返回结果
            return array[index];
        }
        //查询值不在查询范围中,返回的索引为-1或"-"（插入点索引）,需要获取新的索引
        int newIndex = Math.abs(index);
        if (1 == newIndex) {
            //搜索值不是数组元素,且小于数组内元素,索引值为-1,直接返回第一个元素
            return array[0];
        } else if (array.length + 1 == newIndex) {
            //搜索值不是数组元素,且大于数组内元素,索引值为–(length + 1),直接返回最后一个元素;
            return array[array.length - 1];
        } else {
            //搜索值不是数组元素,且在数组范围内,从1开始计数，得"-插入点索引值"
            //获取插入点左一位索引数据
            float leftValue = array[newIndex - 2];
            //获取插入点右一位索引数据
            float rightValue = array[newIndex - 1];
            //获取平均值
            float avg = (leftValue + rightValue) / 2;
            if (target > avg) {
                //输入值大于平均值,返回右一位索引数据
                return rightValue;
            } else {
                //输入值大于平均值,返回左一位索引数据
                return leftValue;
            }

        }
    }

    /**
     * 资源管理-收款-一键拆分-获取拆分数据
     *
     * @param id 待拆分主表数据id
     * @return 数据
     */
    public List<SplitInfoVo> getReceivePaymentInfo(String id) {
        //初始化回参对象集合
        List<SplitInfoVo> voList = new ArrayList<>();
        if (StringUtils.isBlank(id)) {
            return voList;
        }
        //存在多个id
        List<String> ids = Arrays.asList(id.split(","));
        //获取拆分信息
        List<ReceivePaymentEntity> receivePaymentList = receivePaymentService.getRefundAmountInfo(ids);
        if (CollectionUtils.isEmpty(receivePaymentList)) {
            return voList;
        }
        List<Integer> idList = receivePaymentList.stream().map(p -> p.getId()).collect(Collectors.toList());
        //通过主表id获取收款明细数据
        List<ReceivePaymentDetailEntity> detailEntityList = receivePaymentDetailService.queryByParentIds(idList);
        if (CollectionUtils.isEmpty(detailEntityList)) {
            return voList;
        }
        for (ReceivePaymentEntity payment : receivePaymentList) {
            SplitInfoVo vo = new SplitInfoVo();
            //赋值
            BeanUtils.copyProperties(payment, vo);
            //日期处理
            vo.setTime(DateUtils.format(payment.getTime(), DateUtils.DATE_PATTERN));
            //对应明细数据
            List<SplitDetailInfoVo> detailList = new ArrayList<>();
            for (ReceivePaymentDetailEntity detail : detailEntityList) {
                if (!payment.getId().equals(detail.getParentId())) {
                    continue;
                }
                SplitDetailInfoVo detailInfoVo = new SplitDetailInfoVo();
                //赋值
                BeanUtils.copyProperties(detail, detailInfoVo);
                //退款明细id
                detailInfoVo.setDetailId(detail.getId());
                //退款id默认为空
                detailInfoVo.setId(null);
                //获取退款金额
                ReceivePaymentRefundEntity refundReq = new ReceivePaymentRefundEntity();
                //父id
                refundReq.setParentId(detail.getParentId());
                //明细id
                refundReq.setDetailId(detail.getId());
                //数据有效
                refundReq.setValid(DataIsValidEnum.VALID.getId());
                List<ReceivePaymentRefundEntity> refundList = receivePaymentRefundService.queryAll(refundReq);
                //退款金额默认为0
                BigDecimal refundAmount = new BigDecimal("0");
                if(!CollectionUtils.isEmpty(refundList)){
                    if(StringUtil.isNotEmpty(refundList.get(0).getRefundAmount())){
                        //获取老的退款金额
                        refundAmount = refundList.get(0).getRefundAmount();
                    }
                    //退款id
                    detailInfoVo.setId(refundList.get(0).getId());
                }
                detailInfoVo.setRefundAmount(refundAmount);

                detailList.add(detailInfoVo);
            }

            vo.setDetailList(detailList);
            voList.add(vo);
        }
        return voList;
    }


    /**
     * 退款新增
     *
     * @param reqList 新增对象
     */
    public void addRefundAmount(List<SplitInfoReq> reqList) {
        if (CollectionUtils.isEmpty(reqList)) {
            return;
        }
        List<ReceivePaymentRefundEntity> refundEntityList = new ArrayList<>();
        for (SplitInfoReq splitInfo : reqList) {
            if (CollectionUtils.isEmpty(splitInfo.getDetailList())) {
                continue;
            }
            //获取明细数据
            List<SplitDetailInfoReq> detailList = splitInfo.getDetailList();
            for (SplitDetailInfoReq detail : detailList) {
                if (null == detail.getId()) {
                    //退款明细新增
                    ReceivePaymentRefundEntity refund = new ReceivePaymentRefundEntity();
                    //赋值
                    BeanUtils.copyProperties(detail, refund);
                    //创建时间
                    refund.setCreateDate(new Date());
                    //数据设为有效
                    refund.setValid(DataIsValidEnum.VALID.getId());

                    refundEntityList.add(refund);
                } else {
                    //修改
                    ReceivePaymentRefundEntity refundUpdate = new ReceivePaymentRefundEntity();
                    //更新退款金额
                    refundUpdate.setRefundAmount(detail.getRefundAmount());
                    //修改时间
                    refundUpdate.setModifyTime(new Date());
                    //主键id
                    refundUpdate.setId(detail.getId());

                    receivePaymentRefundService.update(refundUpdate);
                }
                //更新明细中的退款金额
                ReceivePaymentDetailEntity updateDetail = new ReceivePaymentDetailEntity();
                updateDetail.setRefundAmount(detail.getRefundAmount());
                updateDetail.setId(detail.getDetailId());
                receivePaymentDetailService.update(updateDetail);
            }
        }

        if (CollectionUtils.isEmpty(refundEntityList)) {
            return;
        }
        //批量新增
        receivePaymentRefundService.addList(refundEntityList);
    }


    /**
     * 获取明细
     *
     * @param id 收款主表id
     * @return 收款明细、拆分明细、退款明细、附件明细
     */
    public ReceivePaymentDetailVo getAllDetail(Integer id) {
        //初始化回参对象
        ReceivePaymentDetailVo vo = new ReceivePaymentDetailVo();
        if (null == id) {
            return vo;
        }
        //第一步：获取收款主表信息
        ReceivePaymentEntity receivePayment = receivePaymentService.queryById(id);
        if (null == receivePayment || null == receivePayment.getId()) {
            return vo;
        }
        //主表数据赋值
        BeanUtils.copyProperties(receivePayment, vo);
        //日期处理
        vo.setTime(DateUtils.format(receivePayment.getTime(), DateUtils.DATE_PATTERN));

        //第二步：获取收款明细数据
        getReceivePaymentDetail(id, vo);

        //第三步：获取拆分明细
        getSplitDetail(id, vo);

        //第四步：获取退款明细
        getRefundDetail(id, vo);

        //第五步：获取附件信息
        getAnnexDetail(id, vo);

        //第六步：获取操作日志
        getOperatorLogInfo(id, vo);

        return vo;
    }

    /**
     * 获取操作日志
     * @param id 收款主表id
     * @param vo 回参对象
     */
    private void getOperatorLogInfo(Integer id, ReceivePaymentDetailVo vo) {
        //第四步：获取对应日志信息
        DataInfoLogEntity logReq = new DataInfoLogEntity();
        //主表id
        logReq.setParentId(id);
        //模块id
        logReq.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        //查询结果
        List<DataInfoLogEntity> dataInfoLog = dataInfoLogService.queryAll(logReq);
        if (!CollectionUtils.isEmpty(dataInfoLog)) {
            List<DataInfoLogVo> logVos = new ArrayList<>();
            for (DataInfoLogEntity log : dataInfoLog) {
                DataInfoLogVo logVo = new DataInfoLogVo();
                //赋值
                BeanUtils.copyProperties(log, logVo);
                //日期处理
                logVo.setOperationTime(DateUtils.format(log.getOperationTime(), DateUtils.DATE_TIME_PATTERN));
                //操作类型
                logVo.setOperationType(OperationTypeEnum.getDescById(log.getOperationType()));

                logVos.add(logVo);
            }

            vo.setLogList(logVos);
        }
    }

    /**
     * 获取附件详情
     *
     * @param id 收款id
     * @param vo 回参实体
     */
    private void getAnnexDetail(Integer id, ReceivePaymentDetailVo vo) {
        AnnexEntity annex = new AnnexEntity();
        //设置模块id
        annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        //设置父id
        annex.setParentId(id);
        //设置数据有效
        annex.setValid(DataIsValidEnum.VALID.getId());
        //调用接口查询附件信息
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if (CollectionUtils.isEmpty(annexList)) {
            return;
        }
        List<AnnexVo> annexVos = annexList.stream().map(p -> {
            AnnexVo annexVo = new AnnexVo();
            //赋值
            BeanUtils.copyProperties(p, annexVo);
            //上传时间转换
            annexVo.setUploadTime(DateUtils.format(p.getUploadTime(), DateUtils.DATE_TIME_PATTERN));
            //设置附件为旧附件,用以区分修改时附件状态
            annexVo.setNews(0);

            return annexVo;
        }).collect(Collectors.toList());

        vo.setAnnexList(annexVos);
    }

    /**
     * 获取退款明细
     *
     * @param id 收款id
     * @param vo 回参实体
     */
    private void getRefundDetail(Integer id, ReceivePaymentDetailVo vo) {
        ReceivePaymentRefundEntity refundEntityReq = new ReceivePaymentRefundEntity();
        //设置父id
        refundEntityReq.setParentId(id);
        //数据有效性
        refundEntityReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentRefundEntity> refundEntityList = receivePaymentRefundService.queryAll(refundEntityReq);
        if (CollectionUtils.isEmpty(refundEntityList)) {
            return;
        }
        //初始化回参集合
        List<RefundDetailVo> refundList = new ArrayList<>();
        for (ReceivePaymentRefundEntity refundEntity : refundEntityList) {
            RefundDetailVo infoVo = new RefundDetailVo();
            //赋值
            BeanUtils.copyProperties(refundEntity, infoVo);

            refundList.add(infoVo);
        }

        vo.setRefundList(refundList);
    }

    /**
     * 通过收款id获取拆分明细
     *
     * @param id 收款id
     * @param vo 回参实体
     */
    private void getSplitDetail(Integer id, ReceivePaymentDetailVo vo) {
        ReceivePaymentSplitEntity splitReq = new ReceivePaymentSplitEntity();
        //设置父id
        splitReq.setParentId(id);
        //数据有效性
        splitReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentSplitEntity> splitEntityList = receivePaymentSplitService.queryAll(splitReq);
        if (CollectionUtils.isEmpty(splitEntityList)) {
            return;
        }
        //初始化回参集合
        List<SplitDetailInfoVo> splitList = new ArrayList<>();
        for (ReceivePaymentSplitEntity splitEntity : splitEntityList) {
            SplitDetailInfoVo infoVo = new SplitDetailInfoVo();
            //赋值
            BeanUtils.copyProperties(splitEntity, infoVo);

            splitList.add(infoVo);
        }

        vo.setSplitList(splitList);
    }

    /**
     * 通过收款id获取收款明细
     *
     * @param id 收款id
     * @param vo 回参实体
     */
    private void getReceivePaymentDetail(Integer id, ReceivePaymentDetailVo vo) {
        ReceivePaymentDetailEntity childReq = new ReceivePaymentDetailEntity();
        //设置父id
        childReq.setParentId(id);
        //设置数据有效性
        childReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentDetailEntity> childList = receivePaymentDetailService.queryAll(childReq);
        if (CollectionUtils.isEmpty(childList)) {
            return;
        }
        //初始化回参集合
        List<ReceivePaymentDetailInfoVo> detailList = new ArrayList<>();
        for (ReceivePaymentDetailEntity child : childList) {
            ReceivePaymentDetailInfoVo infoVo = new ReceivePaymentDetailInfoVo();
            //赋值
            BeanUtils.copyProperties(child, infoVo);
            //日期转换
            infoVo.setClaimDate(DateUtils.format(child.getClaimDate(), DateUtils.DATE_PATTERN));

            detailList.add(infoVo);
        }
        vo.setDetailList(detailList);
    }


    /**
     * 收款首页-箱体操作
     *
     * @param req
     */
    public R operation(OperationReq req, UserEntity user) {
        if (null == req.getId() || null == req.getOperation()) {
            return R.buildError(ResultStatusEnum.SYSTEM_ERROR);
        }
        ReceivePaymentEntity receivePaymentEntity = new ReceivePaymentEntity();
        //设置修改主键
        receivePaymentEntity.setId(req.getId());
        //修改时间
        receivePaymentEntity.setModifyTime(new Date());

        //新增日志信息
        DataInfoLogEntity dataInfoLog = new DataInfoLogEntity();
        //模块主表id
        dataInfoLog.setParentId(req.getId());
        //模块id
        dataInfoLog.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        //操作人编码
        dataInfoLog.setOperationCode(user.getCode());
        //操作人名称
        dataInfoLog.setOperationName(user.getName());
        //操作时间
        dataInfoLog.setOperationTime(new Date());
        //操作内容
        dataInfoLog.setOperationContent("单据操作");

        switch (req.getOperation()) {
            case 1:
                //收款招领,将登记箱改为招领箱
                receivePaymentEntity.setStatus(MoneyOperationStatusEnum.FIND_BOX.getId());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.FIND_BOX.getId());
                break;
            case 2:
                //招领退回,单据退回到登记箱(收款单据关联合同或者结汇发票，不允许退回到草稿箱)
                if (checkIsCanReturn(req.getId())) {
                    receivePaymentEntity.setStatus(MoneyOperationStatusEnum.REGISTRATION_BOX.getId());
                    //操作类型
                    dataInfoLog.setOperationType(OperationTypeEnum.REGISTRATION_BOX.getId());
                } else {
                    return R.buildError(ResultStatusEnum.RECEIVE_PAYMENT_ERROR_RETURN_BOX);
                }
                break;
            case 3:
                //确认箱退回,单据到招领箱,明细数据的已确认改为未确认
                updateDetailConfirmedInfo(req.getId());
                receivePaymentEntity.setStatus(MoneyOperationStatusEnum.FIND_BOX.getId());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.CONFIRM_RETURN.getId());
                break;
            case 4:
                //点击拆分完成,单据到完成箱
                receivePaymentEntity.setStatus(MoneyOperationStatusEnum.COMPLETION_BOX.getId());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.SPLIT_COMPLETE.getId());
                break;
            case 5:
                //点击完成退回,单据到确认箱
                receivePaymentEntity.setStatus(MoneyOperationStatusEnum.CONFIRMATION_BOX.getId());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.COMPLETE_RETURN.getId());
                break;
            case 6:
                //还原 点击还原,将垃圾箱数据还原到登记箱
                receivePaymentEntity.setStatus(MoneyOperationStatusEnum.REGISTRATION_BOX.getId());
                //操作类型
                dataInfoLog.setOperationType(OperationTypeEnum.REDUCTION.getId());
                break;
        }
        //调用接口修改
        receivePaymentService.update(receivePaymentEntity);

        dataInfoLogService.insert(dataInfoLog);

        return R.build(ResultStatusEnum.SUCCESS);
    }

    /**
     * 修改明细数据
     *
     * @param id 收款主表id
     */
    private void updateDetailConfirmedInfo(Integer id) {
        ReceivePaymentDetailEntity queryReq = new ReceivePaymentDetailEntity();
        queryReq.setParentId(id);
        queryReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentDetailEntity> detailEntities = receivePaymentDetailService.queryAll(queryReq);
        if (CollectionUtils.isEmpty(detailEntities)) {
            return;
        }
        for (ReceivePaymentDetailEntity detailEntity : detailEntities) {
            detailEntity.setModifyTime(new Date());
            //已确认(0:待确认 1:已确认)
            detailEntity.setConfirmed(0);

            receivePaymentDetailService.update(detailEntity);
        }

    }

    /**
     * 校验招领箱数据是否可以退回
     *
     * @param id 收款id
     * @return true:可退回 false:不能退回
     */
    private boolean checkIsCanReturn(Integer id) {
        ReceivePaymentDetailEntity queryReq = new ReceivePaymentDetailEntity();
        queryReq.setParentId(id);
        queryReq.setValid(DataIsValidEnum.VALID.getId());
        List<ReceivePaymentDetailEntity> detailEntities = receivePaymentDetailService.queryAll(queryReq);
        if (CollectionUtils.isEmpty(detailEntities)) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 批量删除
     *
     * @param ids 删除id集合
     */
    public void batchDelete(String ids) {
        if (StringUtils.isBlank(ids)) {
            return;
        }
        //多个id以英文逗号隔开
        List<String> newIds = Arrays.asList(ids.split(","));
        //获取收款
        List<ReceivePaymentEntity> receivePaymentList = receivePaymentService.getReceivePaymentByIds(newIds);
        if (CollectionUtils.isEmpty(receivePaymentList)) {
            return;
        }
        for (ReceivePaymentEntity receivePayment : receivePaymentList) {
            //只删除登记箱、垃圾箱数据
            Integer status = receivePayment.getStatus();
            boolean flag = status.equals(MoneyOperationStatusEnum.REGISTRATION_BOX.getId()) ||
                    status.equals(MoneyOperationStatusEnum.TRASH_CAN.getId());
            if (flag) {
                deleteReceivePayment(receivePayment.getId(), status);
            }
        }
    }

    /**
     * 删除收款信息
     *
     * @param id     收款id
     * @param status 收款箱体
     */
    private void deleteReceivePayment(Integer id, Integer status) {
        ReceivePaymentEntity receivePaymentReq = new ReceivePaymentEntity();
        receivePaymentReq.setId(id);
        receivePaymentReq.setModifyTime(new Date());
        if (status.equals(MoneyOperationStatusEnum.REGISTRATION_BOX.getId())) {
            //登记箱删除,数位改为垃圾箱
            receivePaymentReq.setStatus(MoneyOperationStatusEnum.TRASH_CAN.getId());
            receivePaymentService.update(receivePaymentReq);
            return;
        } else {
            //垃圾箱删除,将主数据设为无效
            receivePaymentReq.setValid(DataIsValidEnum.INVALID.getId());
            receivePaymentService.update(receivePaymentReq);
        }
        //获取对应明细数据
        ReceivePaymentDetailEntity detailEntity = new ReceivePaymentDetailEntity();
        detailEntity.setParentId(id);
        detailEntity.setValid(DataIsValidEnum.VALID.getId());

        List<ReceivePaymentDetailEntity> detailList = receivePaymentDetailService.queryAll(detailEntity);
        if (CollectionUtils.isEmpty(detailList)) {
            return;
        }
        //2.将所有对应有效的明细数据设为无效
        for (ReceivePaymentDetailEntity detail : detailList) {
            ReceivePaymentDetailEntity detailReq = new ReceivePaymentDetailEntity();
            detailReq.setId(detail.getId());
            detailReq.setModifyTime(new Date());
            detailReq.setValid(DataIsValidEnum.INVALID.getId());

            receivePaymentDetailService.update(detailReq);
        }

        //3.获取对应所有附件
        AnnexEntity annex = new AnnexEntity();
        annex.setModuleId(ModuleTypeEnum.MONEY_RECEIVE_PAYMENT.getId());
        annex.setParentId(id);
        annex.setValid(DataIsValidEnum.VALID.getId());
        List<AnnexEntity> annexList = annexService.queryAll(annex);
        if (CollectionUtils.isEmpty(annexList)) {
            return;
        }
        //3.删除所有对应的有效的附件
        for (AnnexEntity annexData : annexList) {
            AnnexEntity annexReq = new AnnexEntity();
            annexReq.setId(annexData.getId());
            annexReq.setUpdateTime(new Date());
            annexReq.setValid(DataIsValidEnum.INVALID.getId());

            annexService.update(annexReq);
        }
    }

    /**
     * 资源管理-收款-修改标记颜色
     *
     * @param req 入参实体
     */
    public void updateMarkColor(OperationReq req) {
        if (null == req || null == req.getId()) {
            return;
        }
        ReceivePaymentEntity receivePaymentReq = new ReceivePaymentEntity();
        //设置修改主键
        receivePaymentReq.setId(req.getId());
        //设修改时间
        receivePaymentReq.setModifyTime(new Date());
        //设置标记颜色
        receivePaymentReq.setMarkColor(req.getColor());
        //更新标记颜色
        receivePaymentService.updateMarkColor(receivePaymentReq);
    }

    /**
     * 一键拆分保存
     *
     * @param reqList
     */
    public void saveSplitInfo(List<SplitInfoReq> reqList) {
        if (CollectionUtils.isEmpty(reqList)) {
            return;
        }
        for (SplitInfoReq splitInfoReq : reqList) {
            if (CollectionUtils.isEmpty(splitInfoReq.getDetailList())) {
                continue;
            }
            for (SplitDetailInfoReq splitDetail : splitInfoReq.getDetailList()) {
                //拆分金额
                BigDecimal splitAmount = splitDetail.getSplitAmount();
                if (StringUtils.isEmpty(splitDetail.getInvoiceNumber()) || !StringUtil.isNotEmpty(splitAmount)) {
                    //发票为空或者拆分金额为空,跳过
                    continue;
                }
                //获取对应收款明细数据
                ReceivePaymentDetailEntity detailInfo = receivePaymentDetailService.queryById(splitDetail.getDetailId());
                //已分摊金额
                BigDecimal allocatedAmount = new BigDecimal("0");
                if (StringUtil.isNotEmpty(detailInfo.getAllocatedAmount())) {
                    allocatedAmount = detailInfo.getAllocatedAmount();
                }
                //新的已分摊金额 = 拆分前已分摊金额 + 本次拆分金额
                BigDecimal newAllocatedAmount = allocatedAmount.add(splitAmount);

                //未分摊金额
                BigDecimal unallocatedAmount = detailInfo.getUnallocatedAmount();
                //新的未分摊金额 = 拆分前未分摊金额 - 本次拆分金额
                BigDecimal newUnallocatedAmount = unallocatedAmount.subtract(splitAmount);
                //初始化收款明细对象
                ReceivePaymentDetailEntity updateReq = new ReceivePaymentDetailEntity();
                updateReq.setId(detailInfo.getId());
                updateReq.setAllocatedAmount(newAllocatedAmount);
                updateReq.setUnallocatedAmount(newUnallocatedAmount);
                //更新已分摊金额、未分摊金额
                receivePaymentDetailService.update(updateReq);

                //保存拆分信息
                ReceivePaymentSplitEntity splitEntity = new ReceivePaymentSplitEntity();
                //赋值
                BeanUtils.copyProperties(splitDetail, splitEntity);
                //创建日期
                splitEntity.setCreateDate(new Date());
                //数据有效
                splitEntity.setValid(DataIsValidEnum.VALID.getId());

                //保存数据
                receivePaymentSplitService.insert(splitEntity);
            }
        }
    }

    /**
     * 一键拆分删除
     * @param ids 要删除的拆分id集合
     */
    public void deleteSplit(Integer[] ids){
        if(null == ids || ids.length == 0){
            return;
        }
        for(Integer id : ids){
            //获取拆分信息
            ReceivePaymentSplitEntity split = receivePaymentSplitService.queryById(id);
            //拆分金额
            BigDecimal splitAmount = split.getSplitAmount();
            //获取收款明细信息
            ReceivePaymentDetailEntity detail = receivePaymentDetailService.queryById(split.getDetailId());
            //回退已拆分数据
            //已分摊金额
            BigDecimal allocatedAmount = new BigDecimal("0");
            if (StringUtil.isNotEmpty(detail.getAllocatedAmount())) {
                allocatedAmount = detail.getAllocatedAmount();
            }
            //新的已分摊金额 = 拆分前已分摊金额 - 本次拆分金额
            BigDecimal newAllocatedAmount = allocatedAmount.subtract(splitAmount);

            //未分摊金额
            BigDecimal unallocatedAmount = detail.getUnallocatedAmount();
            //新的未分摊金额 = 拆分前未分摊金额 + 本次拆分金额
            BigDecimal newUnallocatedAmount = unallocatedAmount.add(splitAmount);
            //初始化收款明细对象
            ReceivePaymentDetailEntity updateReq = new ReceivePaymentDetailEntity();
            updateReq.setId(detail.getId());
            updateReq.setAllocatedAmount(newAllocatedAmount);
            updateReq.setUnallocatedAmount(newUnallocatedAmount);
            //更新已分摊金额、未分摊金额
            receivePaymentDetailService.update(updateReq);

            //将该拆分设为无效
            ReceivePaymentSplitEntity splitEntity = new ReceivePaymentSplitEntity();
            splitEntity.setId(id);
            //删除时间
            splitEntity.setModifyTime(new Date());
            //数据无效
            splitEntity.setValid(DataIsValidEnum.INVALID.getId());

            //保存数据
            receivePaymentSplitService.update(splitEntity);

        }
    }


    //************************收款统计*******************************************

    /**
     * 获取String类型不为空数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private String getNotNullOfStringInfo(String value) {
        if (StringUtils.isEmpty(value)) {
            return "";
        } else {
            return value;
        }
    }

    /**
     * 获取BigDecimal类型不为空的数据
     *
     * @param value 目标数据
     * @return 不为空数据
     */
    private BigDecimal getNotNullOfBigDecimalInfo(BigDecimal value) {
        if (StringUtil.isNotEmpty(value)) {
            return value;
        } else {
            return new BigDecimal("0");
        }
    }

    /**
     * 收款金额明细统计-集合
     *
     * @param req
     * @return
     */
    private List<CollectionStatistics1Rsp> collectionStatistics1RspList(CollectionStatistics1Req req, String code) {
        if (StringUtil.isObjectFieldEmpty(req)) {
            //查询对象全部为空时,只查询当前用户数据
            req.setOperationCode(code);
        }
        List<CollectionStatistics1Rsp> collectionStatistics1RspList = receivePaymentService.collectionStatistics1(req);
        for (CollectionStatistics1Rsp p : collectionStatistics1RspList) {
            p.setBankDeduction(p.getForeignBankDeductions());
            p.setCollectionAmountRmb(p.getCollectionAmount().multiply(p.getRmb()));
            p.setAmountClaimedRmb(p.getClaimed().multiply(p.getRmb()));

            p.setTimeStr(DateUtils.format(p.getTime(), DateUtils.DATE_PATTERN));
            p.setClaimDateStr(DateUtils.format(p.getClaimDate(), DateUtils.DATE_PATTERN));
            p.setMinClaimDateStr(DateUtils.format(p.getMinClaimDate(), DateUtils.DATE_PATTERN));


            BigDecimal rmbRate = p.getRmb();
            BigDecimal usdRate = p.getUsd();

            if (p.getCurrencyEnglishName().equals("人民币") || p.getCurrencyEnglishName().equals("RMB")) {
                if(usdRate.compareTo(BigDecimal.valueOf(1)) == 1){
                    p.setClaimedUsd(p.getClaimed().divide(usdRate, 2, BigDecimal.ROUND_HALF_UP));
                }else{
                    p.setClaimedUsd(p.getClaimed().multiply(usdRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                }
                p.setClaimedRmb(p.getClaimed());

            }else {
                p.setClaimedUsd((p.getClaimed().multiply(usdRate)).divide(BigDecimal.valueOf(1),2,BigDecimal.ROUND_HALF_UP));
                p.setClaimedRmb(p.getClaimed().multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
            }

        }
        return collectionStatistics1RspList;
    }

    /**
     * 收款金额明细统计-分页
     * @param req 入参查询对象
     * @param code 档期按登录用户编码
     * @return 收款统计信息
     */
    public PageInfo<CollectionStatistics1Rsp> collectionStatistics1ListByPage(CollectionStatistics1Req req, String code) {
        List<CollectionStatistics1Rsp> collectionStatistics1RspList = collectionStatistics1RspList(req, code);
        PageInfo<CollectionStatistics1Rsp> pageInfo = new PageInfo<>(collectionStatistics1RspList);
        return pageInfo;
    }

    /**
     * 收款金额明细统计-导出
     *
     * @param req
     * @return
     */
    public JSONObject collectionStatistics1Export(CollectionStatistics1Req req, String code) {
        List<CollectionStatistics1Rsp> collectionStatistics1RspList = collectionStatistics1RspList(req, code);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionFirstInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(collectionStatistics1RspList)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionFirstInfoExport(data, collectionStatistics1RspList);
        obj.put("data", data);
        return obj;
    }

    private JSONArray getTitleCollectionFirstInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("收款日期");
        obj.add("收款编号");
        obj.add("客户名称");
        obj.add("收汇金额");
        obj.add("入账金额");
        obj.add("银行扣费");
        obj.add("实际收汇金额");
        obj.add("币种");
        obj.add("实际合同认领金额");
        obj.add("实际合同认领金额USD");
        obj.add("价格术语");
        obj.add("认领业务员名称");
        obj.add("认领客户名称");
        obj.add("认领合同号");
        obj.add("客户来源");
        obj.add("客户属性");
        obj.add("认领日期");
        obj.add("现在客户简称");
        obj.add("第一次认领日期");


//        obj.add("操作员编码");
//        obj.add("操作员名称");
//        obj.add("收款银行");
//        obj.add("收款账号");
//        obj.add("国内银行扣费");
//        obj.add("实际合同认领金额RMB");
//        obj.add("具体国外银行扣费");
//        obj.add("具体国内银行扣费");
//        obj.add("销售合同建单业务员");
//        obj.add("收汇");
//        obj.add("入账");
//        obj.add("现在客户名称");
//        obj.add("业务员编码");
//        obj.add("业务员名称");
        return obj;
    }

    private void excelCollectionFirstInfoExport(JSONArray data, List<CollectionStatistics1Rsp> list) {
        //收汇金额
        BigDecimal collectionAmount = new BigDecimal("0");
        //入账金额
        BigDecimal entryAmount = new BigDecimal("0");
//        //国外银行扣费
//        BigDecimal bankDeductionExcept = new BigDecimal("0");
//        //国内银行扣费
//        BigDecimal bankDeductionCapital = new BigDecimal("0");
        //实际收汇金额
        BigDecimal actualCollectionAmount = new BigDecimal("0");
        //实际合同认领金额
        BigDecimal claimed = new BigDecimal("0");
//        //实际合同认领金额RMB
//        BigDecimal claimedRmb = new BigDecimal("0");
        //实际合同认领金额USD
        BigDecimal claimedUsd = new BigDecimal("0");
//        //具体国外银行扣费
//        BigDecimal foreignBankDeductions = new BigDecimal("0");
//        //具体国内银行扣费
//        BigDecimal domesticBankCharge = new BigDecimal("0");
        //银行扣费
        BigDecimal bankDeduction = new BigDecimal("0");
//        //收汇
//        BigDecimal collectionAmountRmb = new BigDecimal("0");
//        //入账
//        BigDecimal amountClaimedRmb = new BigDecimal("0");


        int i = 0;
        for (CollectionStatistics1Rsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getTimeStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBillNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getEntryAmount()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getBankDeductionExcept()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getBankDeduction()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getActualCollectionAmount()));
            infoList.add(getNotNullOfStringInfo(vo.getCurrencyEnglishName()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getClaimed()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getClaimedUsd()));
            infoList.add(getNotNullOfStringInfo(vo.getPriceTermsName()));
            infoList.add(getNotNullOfStringInfo(vo.getClaimSalesman()));
            infoList.add(getNotNullOfStringInfo(vo.getClaimCustomer()));
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerSource()));
            infoList.add(getNotNullOfStringInfo(vo.getAttributesOfCustomers()));
            infoList.add(getNotNullOfStringInfo(vo.getClaimDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getAbbreviation()));
            infoList.add(getNotNullOfStringInfo(vo.getMinClaimDateStr()));


//            infoList.add(getNotNullOfStringInfo(vo.getOperationNo()));
//            infoList.add(getNotNullOfStringInfo(vo.getOperator()));
//            infoList.add(getNotNullOfStringInfo(vo.getBankName()));
//            infoList.add(getNotNullOfStringInfo(vo.getAccountNo()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getBankDeductionCapital()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getClaimedRmb()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductions()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getDomesticBankCharge()));
//            infoList.add(getNotNullOfStringInfo(vo.getContractSalesman()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmountRmb()));
//            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountClaimedRmb()));
//            infoList.add(getNotNullOfStringInfo(vo.getNowCustomerName()));
//            infoList.add(getNotNullOfStringInfo(vo.getSalesmanCode()));
//            infoList.add(getNotNullOfStringInfo(vo.getSalesman()));

            if (StringUtil.isNotEmpty(vo.getCollectionAmount())) {
                collectionAmount = collectionAmount.add(vo.getCollectionAmount());
            }
            if (StringUtil.isNotEmpty(vo.getEntryAmount())) {
                entryAmount = entryAmount.add(vo.getEntryAmount());
            }
//            if(StringUtil.isNotEmpty(vo.getBankDeductionExcept())){
//                bankDeductionExcept = bankDeductionExcept.add(vo.getBankDeductionExcept());
//            }
//            if(StringUtil.isNotEmpty(vo.getBankDeductionCapital())){
//                bankDeductionCapital = bankDeductionCapital.add(vo.getBankDeductionCapital());
//            }
            if (StringUtil.isNotEmpty(vo.getActualCollectionAmount())) {
                actualCollectionAmount = actualCollectionAmount.add(vo.getActualCollectionAmount());
            }
            if (StringUtil.isNotEmpty(vo.getClaimed())) {
                claimed = claimed.add(vo.getClaimed());
            }
//            if(StringUtil.isNotEmpty(vo.getClaimedRmb())){
//                claimedRmb = claimedRmb.add(vo.getClaimedRmb());
//            }
            if(StringUtil.isNotEmpty(vo.getClaimedUsd())){
                claimedUsd = claimedUsd.add(vo.getClaimedUsd());
            }
//            if(StringUtil.isNotEmpty(vo.getForeignBankDeductions())){
//                foreignBankDeductions = foreignBankDeductions.add(vo.getForeignBankDeductions());
//            }
//            if(StringUtil.isNotEmpty(vo.getDomesticBankCharge())){
//                domesticBankCharge = domesticBankCharge.add(vo.getDomesticBankCharge());
//            }
            if (StringUtil.isNotEmpty(vo.getBankDeduction())) {
                bankDeduction = bankDeduction.add(vo.getBankDeduction());
            }
//            if(StringUtil.isNotEmpty(vo.getCollectionAmountRmb())){
//                collectionAmountRmb = collectionAmountRmb.add(vo.getCollectionAmountRmb());
//            }
//            if(StringUtil.isNotEmpty(vo.getAmountClaimedRmb())){
//                amountClaimedRmb = amountClaimedRmb.add(vo.getAmountClaimedRmb());
//            }
            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(collectionAmount);
        titleList.add(entryAmount);
        titleList.add(bankDeduction);
        titleList.add(actualCollectionAmount);
        titleList.add("");
        titleList.add(claimed);
        titleList.add(claimedUsd);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");


//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add(bankDeductionCapital);
//        titleList.add("");
//        titleList.add(claimedRmb);
//
//        titleList.add("");
//        titleList.add(foreignBankDeductions);
//        titleList.add(domesticBankCharge);
//        titleList.add("");
//        titleList.add(bankDeduction);
//        titleList.add("");
//        titleList.add("");
//        titleList.add(collectionAmountRmb);
//        titleList.add(amountClaimedRmb);
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");
//        titleList.add("");

        data.add(titleList);

    }

    /**
     * 按发票应收款统计 或者 按发票应收统计价格术语不同 -集合
     *
     * @param req
     * @return
     */
    private List<CollectionStatistics2Rsp> collectionStatisticsTwoRspList(CollectionStatistics2Req req, String code) {
        if (StringUtil.isObjectIgnoreFieldEmpty(req,"pageType")) {
            //查询对象全部为空时,只查询当前用户数据
            req.setOperationCode(code);
        }
        List<CollectionStatistics2Rsp> collectionStatistics2RspList = receivePaymentService.collectionStatistics2(req);

        for (CollectionStatistics2Rsp p : collectionStatistics2RspList) {
            p.setInvoiceStr(DateUtils.format(p.getInvoiceDate(), DateUtils.DATE_PATTERN));

            BigDecimal rmbRate = p.getRmbRate();
            BigDecimal usdRate = p.getUsdRate();

            if (p.getCurrencyEnglishName().equals("人民币") || p.getCurrencyEnglishName().equals("RMB")) {
                if(usdRate.compareTo(BigDecimal.valueOf(1)) == 1){
                    p.setInvoiceMoneyUsd(p.getInvoiceMoney().divide(usdRate, 4, BigDecimal.ROUND_HALF_UP));
                    p.setCollectionAmountUsd(p.getCollectionAmount().divide(usdRate, 4, BigDecimal.ROUND_HALF_UP));
                    p.setRefundAmountUsd(p.getRefundAmount().divide(usdRate, 4, BigDecimal.ROUND_HALF_UP));


                }else{
                    p.setInvoiceMoneyUsd(p.getInvoiceMoney().multiply(usdRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
                    p.setCollectionAmountUsd(p.getCollectionAmount().multiply(usdRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
                    p.setRefundAmountUsd(p.getRefundAmount().multiply(usdRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));

                }
                p.setInvoiceMoneyRmb(p.getInvoiceMoney().setScale(4, BigDecimal.ROUND_HALF_UP));
                p.setCollectionAmountRmb(p.getCollectionAmount().setScale(4, BigDecimal.ROUND_HALF_UP));
                p.setRefundAmountRmb(p.getRefundAmount().setScale(4, BigDecimal.ROUND_HALF_UP));
                p.setAmountClaimedRmb(p.getAmountClaimed().setScale(4, BigDecimal.ROUND_HALF_UP));
            }else {
                p.setInvoiceMoneyUsd((p.getInvoiceMoney().multiply(usdRate)).divide(BigDecimal.valueOf(1),4,BigDecimal.ROUND_HALF_UP));
                p.setInvoiceMoneyRmb(p.getInvoiceMoney().multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
                p.setCollectionAmountUsd((p.getInvoiceMoney().multiply(usdRate)).divide(BigDecimal.valueOf(1),4,BigDecimal.ROUND_HALF_UP));
                p.setCollectionAmountRmb(p.getCollectionAmount().multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
                p.setRefundAmountUsd((p.getRefundAmount().multiply(usdRate)).divide(BigDecimal.valueOf(1),4,BigDecimal.ROUND_HALF_UP));
                p.setRefundAmountRmb(p.getRefundAmount().multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
                p.setAmountClaimedRmb(p.getAmountClaimed().multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 4, BigDecimal.ROUND_HALF_UP));
            }

            BigDecimal res=p.getInvoiceMoney().subtract(p.getAmountClaimed().add(p.getForeignBankDeductions())).setScale(4, BigDecimal.ROUND_HALF_UP);
            /*if (res.compareTo(new BigDecimal(0))<=1){
                p.setUnPayment((p.getInvoiceMoney().subtract(p.getAmountClaimed())).setScale(2, BigDecimal.ROUND_HALF_UP));
            }else {
                p.setUnPayment(res);
            }*/
            p.setUnPayment(res);
            p.setUnPaymentRmb((p.getUnPayment().multiply(rmbRate)).setScale(4, BigDecimal.ROUND_HALF_UP));


            p.setClaimDatStr(DateUtils.format(p.getClaimDate(), DateUtils.DATE_PATTERN));
            p.setMaxClaimDateStr(DateUtils.format(p.getMaxClaimDate(), DateUtils.DATE_PATTERN));
            p.setActualAtdStr(DateUtils.format(p.getActualAtdDate(), DateUtils.DATE_PATTERN));
            //p.setReceivePaymentStr(DateUtils.format(p.getReceivePaymentDate(), DateUtils.DATE_PATTERN));
            try {
                //应收到账日期 发票日期+账期(业务层计算)
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(p.getInvoiceDate());
                calendar.add(Calendar.DATE, Integer.parseInt(p.getPayday()));
                p.setReceivablePayday(DateUtils.format(calendar.getTime(), DateUtils.DATE_PATTERN));

                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

                //应收到账日期
                String receivablePayday = p.getReceivablePayday();
                //最近认领日期
                String maxClaimDateStr = p.getMaxClaimDateStr();
                //当最近认领日期=null   那么逾期=应收日期-当前日期
                if (StringUtils.isEmpty(maxClaimDateStr)) {
                    //应收到账日期
                    Date receivablePaydayDate = format.parse(receivablePayday);
                    //当前日期
                    Date nowDate = new Date();
                    int day = getDiffer(receivablePaydayDate, nowDate);
                    p.setAdvanceCollectionDay("" + 0);
                    p.setOverdue("" + day);
                } else {//当不等于null  且应收货款-已收货款=0是 那么是收款完成
                    //应收到账日期
                    Date receivablePaydayDate = format.parse(receivablePayday);
                    //最近一次认领日期
                    Date nowDate = p.getMaxClaimDate();
                    int day = getDiffer(receivablePaydayDate, nowDate);
                    p.setAdvanceCollectionDay("" + day);

                    BigDecimal invoiceMoney = p.getInvoiceMoney();
                    BigDecimal collectionAmount = p.getCollectionAmount();
                    BigDecimal subtract = invoiceMoney.subtract(collectionAmount);
                    double subtractDou = subtract.doubleValue();
                    if (subtractDou <= 0) {
                        p.setOverdue("收款完成");
                    } else {
                        p.setOverdue("部分收款");
                    }

                }

            } catch (ParseException e) {
                e.printStackTrace();
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
        }
        return collectionStatistics2RspList;
    }

    /**
     * 按发票应收款统计 或者 按发票应收统计价格术语不同 -分页
     *
     * @param req
     * @return
     */
    public PageInfo<CollectionStatistics2Rsp> collectionStatistics2ListByPage(CollectionStatistics2Req req, String code) {
        List<CollectionStatistics2Rsp> collectionStatistics2RspList = collectionStatisticsTwoRspList(req, code);
        PageInfo<CollectionStatistics2Rsp> pageInfo = new PageInfo<>(collectionStatistics2RspList);
        return pageInfo;
    }

    /**
     * 按发票应收款统计 或者 按发票应收统计价格术语不同 -导出
     *
     * @param req
     * @return
     */
    public JSONObject collectionStatisticsTwoExport(CollectionStatistics2Req req, String code) {
        List<CollectionStatistics2Rsp> collectionStatistics2RspList = collectionStatisticsTwoRspList(req, code);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionSecondInfo(req.getPageType());
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(collectionStatistics2RspList)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionSecondInfoExport(data, collectionStatistics2RspList,req.getPageType());
        obj.put("data", data);
        return obj;
    }

    private JSONArray getTitleCollectionSecondInfo(String pageType) {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("发票日期");
        obj.add("客户来源");
        if (pageType.equals("2")){
            obj.add("结汇价格术语");
            obj.add("外销价格术语");
        }else {
            obj.add("价格术语");
        }

        obj.add("客户编码");
        obj.add("客户名称");
        obj.add("业务员");
        obj.add("发票编号");
        obj.add("外销合同号");
        obj.add("币种");
        obj.add("应收货款");
//        obj.add("人民币应收");
        obj.add("应收货款(USD)");
        obj.add("应收货款(RMB)");
        obj.add("已收货款");
        obj.add("未收货款");

        obj.add("未收货款(RMB)");
        obj.add("实收货款");

        obj.add("人民币已收");
        obj.add("人民币实收");
        obj.add("操作员");
        obj.add("最近一次认领日期");
        obj.add("公司");
        obj.add("银行名称");
        obj.add("应收到账日期");
        obj.add("账期");
        obj.add("提前收款天数");
        obj.add("逾期");
        obj.add("运抵国");
        obj.add("实际开船日期");
        obj.add("业务模式");
        obj.add("国外银行扣费（原币）");
        obj.add("国内银行扣费");
        obj.add("退款金额");
        obj.add("人民币退款金额");

        return obj;
    }

    private void excelCollectionSecondInfoExport(JSONArray data, List<CollectionStatistics2Rsp> list,String pageType) {

        //应收货款
        BigDecimal invoiceMoney = new BigDecimal("0");
        //人民币应收
        BigDecimal invoiceMoneyRmb = new BigDecimal("0");
        //美元应收
        BigDecimal invoiceMoneyUsd = new BigDecimal("0");
        //已收货款
        BigDecimal collectionAmount = new BigDecimal("0");
        //未收货款
        BigDecimal unPayment = new BigDecimal("0");
        //未收货款rmb
        BigDecimal unPaymentRmb = new BigDecimal("0");
        //实收货款
        BigDecimal amountClaimed = new BigDecimal("0");

        //人民币已收
        BigDecimal collectionAmountRmb = new BigDecimal("0");
        //人民币实收
        BigDecimal amountClaimedRmb = new BigDecimal("0");
        //国外银行扣费（原币）
        BigDecimal foreignBankDeductions = new BigDecimal("0");
        //国内银行扣费
        BigDecimal domesticBankCharge = new BigDecimal("0");
        //退款金额
        BigDecimal refundAmount = new BigDecimal("0");
        //人民币退款金额
        BigDecimal refundAmountRmb = new BigDecimal("0");


        int i = 0;
        for (CollectionStatistics2Rsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceStr()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerSource()));
            infoList.add(getNotNullOfStringInfo(vo.getPriceTermsName()));
            if (pageType.equals("2")){
                infoList.add(getNotNullOfStringInfo(vo.getEcPriceName()));
            }

            infoList.add(getNotNullOfStringInfo(vo.getCustomerCode()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getBillExchangeSalesman()));
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceNumber()));
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCurrencyEnglishName()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getInvoiceMoney()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getInvoiceMoneyUsd()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getInvoiceMoneyRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnPayment()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnPaymentRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountClaimed()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmountRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountClaimedRmb()));
            infoList.add(getNotNullOfStringInfo(vo.getBillExchangeOperatorName()));
            infoList.add(getNotNullOfStringInfo(vo.getMaxClaimDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBillExchangeCompanyName()));
            infoList.add(getNotNullOfStringInfo(vo.getBillExchangeBankName()));
            infoList.add(getNotNullOfStringInfo(vo.getReceivablePayday()));
            infoList.add(getNotNullOfStringInfo(vo.getPayday()));
            infoList.add(getNotNullOfStringInfo(vo.getAdvanceCollectionDay()));
            infoList.add(getNotNullOfStringInfo(vo.getOverdue()));
            infoList.add(getNotNullOfStringInfo(vo.getEndPlace()));
            infoList.add(getNotNullOfStringInfo(vo.getActualAtdStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBusinessMode()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductions()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getDomesticBankCharge()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getRefundAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getRefundAmountRmb()));

            if (StringUtil.isNotEmpty(vo.getInvoiceMoney())) {
                invoiceMoney = invoiceMoney.add(vo.getInvoiceMoney());
            }
            if (StringUtil.isNotEmpty(vo.getInvoiceMoneyRmb())) {
                invoiceMoneyRmb = invoiceMoneyRmb.add(vo.getInvoiceMoneyRmb());
            }
            if (StringUtil.isNotEmpty(vo.getInvoiceMoneyUsd())) {
                invoiceMoneyUsd = invoiceMoneyUsd.add(vo.getInvoiceMoneyUsd());
            }

            if (StringUtil.isNotEmpty(vo.getCollectionAmount())) {
                collectionAmount = collectionAmount.add(vo.getCollectionAmount());
            }

            if (StringUtil.isNotEmpty(vo.getUnPayment())) {
                unPayment = unPayment.add(vo.getUnPayment());
            }
            if (StringUtil.isNotEmpty(vo.getUnPaymentRmb())) {
                unPaymentRmb = unPaymentRmb.add(vo.getUnPaymentRmb());
            }

            if (StringUtil.isNotEmpty(vo.getAmountClaimed())) {
                amountClaimed = amountClaimed.add(vo.getAmountClaimed());
            }

            if (StringUtil.isNotEmpty(vo.getCollectionAmountRmb())) {
                collectionAmountRmb = collectionAmountRmb.add(vo.getCollectionAmountRmb());
            }
            if (StringUtil.isNotEmpty(vo.getAmountClaimedRmb())) {
                amountClaimedRmb = amountClaimedRmb.add(vo.getAmountClaimedRmb());
            }
            if (StringUtil.isNotEmpty(vo.getForeignBankDeductions())) {
                foreignBankDeductions = foreignBankDeductions.add(vo.getForeignBankDeductions());
            }
            if (StringUtil.isNotEmpty(vo.getDomesticBankCharge())) {
                domesticBankCharge = domesticBankCharge.add(vo.getDomesticBankCharge());
            }

            if (StringUtil.isNotEmpty(vo.getRefundAmount())) {
                refundAmount = refundAmount.add(vo.getRefundAmount());
            }
            if (StringUtil.isNotEmpty(vo.getRefundAmountRmb())) {
                refundAmountRmb = refundAmountRmb.add(vo.getRefundAmountRmb());
            }


            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        if (pageType.equals("2")) {
            titleList.add("");
        }
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(invoiceMoney);
        titleList.add(invoiceMoneyUsd);
        titleList.add(invoiceMoneyRmb);
        titleList.add(collectionAmount);
        titleList.add(unPayment);
        titleList.add(unPaymentRmb);
        titleList.add(amountClaimed);
        titleList.add(collectionAmountRmb);
        titleList.add(amountClaimedRmb);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(foreignBankDeductions);
        titleList.add(domesticBankCharge);
        titleList.add(refundAmount);
        titleList.add(refundAmountRmb);

        data.add(titleList);
    }

    public int getDiffer(Date date1, Date date2) {
        Calendar calendarDate1 = Calendar.getInstance();
        calendarDate1.setTime(date1);
        int year1 = calendarDate1.get(Calendar.YEAR);
        int day1 = calendarDate1.get(Calendar.DAY_OF_YEAR);

        Calendar calendarDate2 = Calendar.getInstance();
        calendarDate2.setTime(date2);
        int year2 = calendarDate2.get(Calendar.YEAR);
        int day2 = calendarDate2.get(Calendar.DAY_OF_YEAR);

        //返回正值是代表左侧日期大于参数日期
        if (year1 != year2) {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {    //闰年
                    timeDistance += 366;
                } else {    //不是闰年
                    timeDistance += 365;
                }
            }
            return timeDistance + (day1 - day2);
        } else {
            return day1 - day2;
        }
    }

    /**
     * 业务员年度认领金额统计-集合
     * @param req
     * @return
     */
    private List<CollectionStatistics3Rsp> collectionStatistics3RspList(CollectionStatistics3Req req){
        List<CollectionStatistics3Rsp> collectionStatistics3RspList = receivePaymentService.collectionStatistics3(req);
        for (CollectionStatistics3Rsp p : collectionStatistics3RspList) {
            p.setClaimDateStr(DateUtils.format(p.getClaimDate(), DateUtils.DATE_PATTERN));
            String currency = p.getCurrency();
            //美金汇率
            BigDecimal usdRate = p.getUsdRate();
            //rmb汇率
            BigDecimal rmbRate = p.getRmbRate();
            //认领金额
            BigDecimal amountClaimed = p.getAmountClaimed();

            if (rmbRate!=null && usdRate!=null && amountClaimed!=null){
                if (currency.equals("人民币") || currency.equals("RMB")) {
                    if(usdRate.compareTo(BigDecimal.valueOf(1)) == 1){
                        p.setAmountClaimedUSD(amountClaimed.divide(usdRate, 2, BigDecimal.ROUND_HALF_UP));
                    }else{
                        p.setAmountClaimedUSD(amountClaimed.multiply(usdRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                    }
                    p.setAmountClaimedRMB(amountClaimed);
                }else{
                    p.setAmountClaimedUSD((amountClaimed.multiply(usdRate)).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                    p.setAmountClaimedRMB(amountClaimed.multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                }
            }


        }
        return collectionStatistics3RspList;
    }
    /**
     * 业务员年度认领金额统计-分页
     *
     * @param req
     * @return
     */
    public PageInfo<CollectionStatistics3Rsp> collectionStatistics3ListByPage(CollectionStatistics3Req req) {
        List<CollectionStatistics3Rsp> collectionStatistics3RspList = collectionStatistics3RspList(req);
        PageInfo<CollectionStatistics3Rsp> pageInfo = new PageInfo<>(collectionStatistics3RspList);
        return pageInfo;
    }

    /**
     * 业务员年度认领金额统计-导出
     *
     * @param req
     * @return
     */
    public JSONObject collectionStatisticsThirdExport(CollectionStatistics3Req req) {
        List<CollectionStatistics3Rsp> collectionStatistics3RspList = collectionStatistics3RspList(req);

        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionThirdInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(collectionStatistics3RspList)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionThirdInfoExport(data, collectionStatistics3RspList);
        obj.put("data", data);
        return obj;
    }

    private JSONArray getTitleCollectionThirdInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("业务员");
        obj.add("认领客户名称");
        obj.add("登记客户名称");
        obj.add("币种");
        obj.add("收款类型");
        obj.add("认领金额USD");
        obj.add("认领金额");
        return obj;
    }

    private void excelCollectionThirdInfoExport(JSONArray data, List<CollectionStatistics3Rsp> list) {
        //认领金额
        BigDecimal amountClaimed = new BigDecimal("0");
        //认领金额USD
        BigDecimal amountClaimedUSD = new BigDecimal("0");
        int i = 0;
        for (CollectionStatistics3Rsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getClaimSalesman()));
            infoList.add(getNotNullOfStringInfo(vo.getClaimCustomer()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getCurrency()));
            infoList.add(getNotNullOfStringInfo(vo.getTypeName()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountClaimedUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getAmountClaimed()));
            if (StringUtil.isNotEmpty(vo.getAmountClaimed())) {
                amountClaimed = amountClaimed.add(vo.getAmountClaimed());
            }
            if (StringUtil.isNotEmpty(vo.getAmountClaimedUSD())) {
                amountClaimedUSD = amountClaimedUSD.add(vo.getAmountClaimedUSD());
            }
            data.add(infoList);
        }
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(amountClaimedUSD);
        titleList.add(amountClaimed);
        data.add(titleList);
    }

    /**
     * 按合同应收款统计--集合
     *
     * @param req
     * @return
     */
    private List<CollectionStatistics4Rsp> collectionStatistics4RspList(CollectionStatistics4Req req, String code) {
        if (StringUtil.isObjectFieldEmpty(req)) {
            //查询对象全部为空时,只查询当前用户数据
            req.setSalesmanCode(code);
        }
        List<CollectionStatistics4Rsp> collectionStatistics4RspList = receivePaymentService.collectionStatistics4(req);
        for (CollectionStatistics4Rsp p : collectionStatistics4RspList) {
            p.setSigningDateStr(DateUtils.format(p.getSigningDate(), DateUtils.DATE_PATTERN));
            //总金额
            BigDecimal totalContractAmount = p.getTotalContractAmount();

            //银行扣费
            BigDecimal foreignBankDeductions = new BigDecimal(0);
            if (p.getForeignBankDeductions() !=null){
                foreignBankDeductions = p.getForeignBankDeductions();
            }

            if(StringUtils.isNotEmpty(p.getContractCurrencyCode())){
                //美金汇率(合同)
                BigDecimal contractUsdRate = new BigDecimal("0");
                if(StringUtil.isNotEmpty(p.getContractUsdRate())){
                    contractUsdRate = p.getContractUsdRate();
                }
                //应收货款(USD)
                p.setReceivableUSD(totalContractAmount.multiply(contractUsdRate));

                p.setForeignBankDeductionsUSD(foreignBankDeductions.multiply(contractUsdRate));
                //rmb汇率(合同)
                BigDecimal contractRmbRate = new BigDecimal("0");
                if(StringUtil.isNotEmpty(p.getContractRmbRate())){
                    contractRmbRate = p.getContractRmbRate();
                }
                //应收折人民币
                if("usd-001".equals(p.getContractCurrencyCode()) || "rmb-001".equals(p.getContractCurrencyCode())){
                    p.setReceivableRMB(totalContractAmount.multiply(contractRmbRate));
                    p.setForeignBankDeductionsRMB(foreignBankDeductions.multiply(contractRmbRate));
                }else {
                    p.setReceivableRMB(totalContractAmount.multiply(contractUsdRate).multiply(contractRmbRate));
                    p.setForeignBankDeductionsRMB(foreignBankDeductions.multiply(contractUsdRate).multiply(contractRmbRate));
                }
            }

            p.setUncollectedUSD(p.getReceivableUSD().subtract(p.getReceivedUSD()));
            p.setUncollectedRMB(p.getReceivableRMB().subtract(p.getReceivedRMB()));

        }
        return collectionStatistics4RspList;
    }

    /**
     * 按合同应收款统计--分页
     *
     * @param req
     * @return
     */
    public PageInfo<CollectionStatistics4Rsp> collectionStatistics4ListByPage(CollectionStatistics4Req req, String code) {
        List<CollectionStatistics4Rsp> collectionStatistics4RspList = collectionStatistics4RspList(req, code);
        PageInfo<CollectionStatistics4Rsp> pageInfo = new PageInfo<>(collectionStatistics4RspList);
        return pageInfo;
    }

    /**
     * 按合同应收款统计--导出
     *
     * @param req 入参实体
     * @return
     */
    public JSONObject collectionStatisticsFourthExport(CollectionStatistics4Req req, String code) {
        List<CollectionStatistics4Rsp> collectionStatistics4RspList = collectionStatistics4RspList(req, code);
        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionFourthInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(collectionStatistics4RspList)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionFourthInfoExport(data, collectionStatistics4RspList);
        obj.put("data", data);
        return obj;
    }

    private JSONArray getTitleCollectionFourthInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("外销合同号");
        obj.add("签约日期");
        obj.add("收款日期");
        obj.add("业务员");
        obj.add("客户名称");
        obj.add("收款币种");
        obj.add("应收货款(USD)");
        obj.add("应收折人民币");
        obj.add("已收货款(USD)");
        obj.add("以折收人民币");
        obj.add("未收货款(USD)");
        obj.add("未收折人民币");
        obj.add("国外银行扣费（USD）");
        obj.add("国外银行扣费折人民币");
        obj.add("赔偿客户(USD)");
        obj.add("赔偿客户折人民币");
        obj.add("实收货款(USD)");
        obj.add("实收折人民币");
        obj.add("公司名称");
        obj.add("银行名称");
        return obj;
    }

    private void excelCollectionFourthInfoExport(JSONArray data, List<CollectionStatistics4Rsp> list) {
        //应收货款(USD)
        BigDecimal receivableUSD = new BigDecimal("0");
        //应收折人民币
        BigDecimal receivableRMB = new BigDecimal("0");
        //已收货款(USD)
        BigDecimal receivedUSD = new BigDecimal("0");
        //以折收人民币
        BigDecimal receivedRMB = new BigDecimal("0");
        //未收货款(USD)
        BigDecimal uncollectedUSD = new BigDecimal("0");
        //未收折人民币
        BigDecimal uncollectedRMB = new BigDecimal("0");

        //银行扣费（USD）
        BigDecimal foreignBankDeductionsUSD = new BigDecimal("0");
        //银行扣费折人民币
        BigDecimal foreignBankDeductionsRMB = new BigDecimal("0");
        //赔偿客户(USD)
        BigDecimal compensateUSD = new BigDecimal("0");
        //赔偿客户折人民币
        BigDecimal compensateRMB = new BigDecimal("0");
        //实收货款(USD)
        BigDecimal actualReceivedUSD = new BigDecimal("0");
        //实收折人民币
        BigDecimal actualReceivedRMB = new BigDecimal("0");


        int i = 0;
        for (CollectionStatistics4Rsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getSigningDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getSalesmanName()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getCurrency()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivableUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivableRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivedUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivedRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUncollectedUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUncollectedRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductionsUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductionsRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCompensateUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCompensateRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getActualReceivedUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getActualReceivedRMB()));
            infoList.add(getNotNullOfStringInfo(vo.getSigningCompanyName()));
            infoList.add(getNotNullOfStringInfo(vo.getBankName()));

            if (StringUtil.isNotEmpty(vo.getReceivableUSD())) {
                receivableUSD = receivableUSD.add(vo.getReceivableUSD());
            }
            if (StringUtil.isNotEmpty(vo.getReceivableRMB())) {
                receivableRMB = receivableRMB.add(vo.getReceivableRMB());
            }
            if (StringUtil.isNotEmpty(vo.getReceivedUSD())) {
                receivedUSD = receivedUSD.add(vo.getReceivedUSD());
            }

            if (StringUtil.isNotEmpty(vo.getReceivedRMB())) {
                receivedRMB = receivedRMB.add(vo.getReceivedRMB());
            }

            if (StringUtil.isNotEmpty(vo.getUncollectedUSD())) {
                uncollectedUSD = uncollectedUSD.add(vo.getUncollectedUSD());
            }
            if (StringUtil.isNotEmpty(vo.getAmountClaimed())) {
                uncollectedRMB = uncollectedRMB.add(vo.getUncollectedRMB());
            }
            if (StringUtil.isNotEmpty(vo.getForeignBankDeductionsUSD())) {
                foreignBankDeductionsUSD = foreignBankDeductionsUSD.add(vo.getForeignBankDeductionsUSD());
            }
            if (StringUtil.isNotEmpty(vo.getForeignBankDeductionsRMB())) {
                foreignBankDeductionsRMB = foreignBankDeductionsRMB.add(vo.getForeignBankDeductionsRMB());
            }
            if (StringUtil.isNotEmpty(vo.getCompensateUSD())) {
                compensateUSD = compensateUSD.add(vo.getCompensateUSD());
            }
            if (StringUtil.isNotEmpty(vo.getCompensateRMB())) {
                compensateRMB = compensateRMB.add(vo.getCompensateRMB());
            }
            if (StringUtil.isNotEmpty(vo.getActualReceivedUSD())) {
                actualReceivedUSD = actualReceivedUSD.add(vo.getActualReceivedUSD());
            }
            if (StringUtil.isNotEmpty(vo.getActualReceivedRMB())) {
                actualReceivedRMB = actualReceivedRMB.add(vo.getActualReceivedRMB());
            }


            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(receivableUSD);
        titleList.add(receivableRMB);
        titleList.add(receivedUSD);
        titleList.add(receivedRMB);
        titleList.add(uncollectedUSD);
        titleList.add(uncollectedRMB);
        titleList.add(foreignBankDeductionsUSD);
        titleList.add(foreignBankDeductionsRMB);
        titleList.add(compensateUSD);
        titleList.add(compensateRMB);
        titleList.add(actualReceivedUSD);
        titleList.add(actualReceivedRMB);
        titleList.add("");
        titleList.add("");

        data.add(titleList);
    }

    /**
     * 获取本月待认领水单
     *
     * @param name 操作员
     * @param code 操作员编码
     * @return 本月待认领水单
     */
    public long getBillNoCount(String name, String code) {
        //初始化查询对象
        StatisticsInfoReq infoReq = new StatisticsInfoReq();
        infoReq.setOperator(name);
        infoReq.setOperationCode(code);
        infoReq.setCreateDateStart(DateUtils.format(DateUtils.getStartTimeOfTheMonth(), DateUtils.DATE_PATTERN));
        infoReq.setCreateDateEnd(DateUtils.format(DateUtils.getEndTimeOfTheMonth(), DateUtils.DATE_PATTERN));
        //查询结果
        return receivePaymentService.getBillNoCount(infoReq);
    }


    /**
     * 返回处理后的FQ信息
     *
     * @param profitStatisticsInfo FQ信息
     * @return 处理后的FQ信息
     */
    private List<ProfitStatisticsVo> getFQInfo(List<ProfitStatisticsRsp> profitStatisticsInfo) {
        //初始化回参对象集合
        List<ProfitStatisticsVo> voList = new ArrayList<>();
        for (ProfitStatisticsRsp profit : profitStatisticsInfo) {
            //初始化回参对象
            ProfitStatisticsVo vo = new ProfitStatisticsVo();
            //对象赋值
            BeanUtils.copyProperties(profit, vo);
            //发票日期
            vo.setInvoiceDate(DateUtils.format(profit.getInvoiceDate()));
            //出运日期
            vo.setCarryDate(DateUtils.format(profit.getCarryDate()));
            //制单日期
            vo.setCreateTime(DateUtils.format(profit.getCreateTime()));

            if ("美元".equals(profit.getMoneyKind()) || "人民币".equals(profit.getMoneyKind())) {
                vo.setReceivableUsd(profit.getInvoiceMoney().multiply(profit.getUsdRate()));
                vo.setReceivableRmb(profit.getInvoiceMoney().multiply(profit.getRmbRate()));
                //应收结汇费用(USD)
                vo.setCostMoneyOfUsd(profit.getCostMoney().multiply(profit.getUsdRate()));
                //应收结汇费用(RMB)
                vo.setCostMoneyOfRmb(profit.getCostMoney().multiply(profit.getRmbRate()));

            } else {
                BigDecimal num = profit.getInvoiceMoney().multiply(profit.getUsdRate());
                vo.setReceivableUsd(num);
                vo.setReceivableRmb(num.multiply(profit.getRmbRate()));

                BigDecimal costNum = profit.getCostMoney().multiply(profit.getUsdRate());
                //应收结汇费用(USD)
                vo.setCostMoneyOfUsd(costNum);
                //应收结汇费用(RMB)
                vo.setCostMoneyOfRmb(costNum.multiply(profit.getRmbRate()));
            }

            //未收折人民币
            vo.setUnCollectionAmountRmb(vo.getReceivableRmb().subtract(profit.getCollectionAmountRmb()));

            //未收货款(USD)
            vo.setUnCollectionAmountUsd(vo.getReceivableUsd().subtract(profit.getCollectionAmountUsd()));

            //应付货款
            BigDecimal costSubtotalSum = new BigDecimal("0");
            if (StringUtil.isNotEmpty(profit.getCostSubtotalSum())) {
                costSubtotalSum = profit.getCostSubtotalSum();
            }
            //已付货款
            BigDecimal actuallyAmount = new BigDecimal("0");
            if (StringUtil.isNotEmpty(profit.getActuallyAmount())) {
                actuallyAmount = profit.getActuallyAmount();
            }
            //未付货款 = 应付货款-已付货款
            BigDecimal unActuallyAmount = costSubtotalSum.subtract(actuallyAmount);
            vo.setUnActuallyAmount(unActuallyAmount);

            //预计退税
            BigDecimal theoreticalTaxRefund = new BigDecimal("0");
            if(StringUtil.isNotEmpty(profit.getTheoreticalTaxRefund())){
                theoreticalTaxRefund = profit.getTheoreticalTaxRefund().setScale(4, BigDecimal.ROUND_HALF_UP);
            }
            vo.setTheoreticalTaxRefund(theoreticalTaxRefund);

            //应收未税货款
            BigDecimal receivableRmb = new BigDecimal("0");
            if(StringUtil.isNotEmpty(vo.getReceivableRmb())){
                receivableRmb = vo.getReceivableRmb();
            }
            //费用小计
            BigDecimal applicationAmountSum = new BigDecimal("0");
            if(StringUtil.isNotEmpty(profit.getApplicationAmountSUM())){
                applicationAmountSum = profit.getApplicationAmountSUM();
            }

            //预计毛利润（含直接费用）=应收未税货款-应付未税货款-费用小计
            BigDecimal estimatedGrossProfit = receivableRmb
                    .subtract(costSubtotalSum)
                    .subtract(applicationAmountSum);
            vo.setEstimatedGrossProfit(estimatedGrossProfit);

            if(StringUtil.isNotEmpty(receivableRmb) && receivableRmb.compareTo(BigDecimal.ZERO) != 0){
                //预计毛利润率（不含费用）=(1-应付未税货款/应收未税货款)*100
                BigDecimal hundred = new BigDecimal("100");
                if(costSubtotalSum.compareTo(BigDecimal.ZERO) == 0){
                    vo.setProfitMargin(new BigDecimal("0"));
                }else {
                    BigDecimal prof = costSubtotalSum.divide(receivableRmb, 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal one = new BigDecimal("1");
                    BigDecimal margin = one.subtract(prof);
                    BigDecimal res = margin.multiply(hundred);
                    vo.setProfitMargin(res);
                }


                //预计毛利润率（含直接费用）=(（应收未税货款-应付未税货款-费用小计）/应收未税货款)*100
                BigDecimal subPrice = receivableRmb.subtract(costSubtotalSum);
                BigDecimal subCost = subPrice.subtract(applicationAmountSum);
                if(subCost.compareTo(BigDecimal.ZERO) == 0){
                    vo.setProfitMarginDirectCost(new BigDecimal("0"));
                }else {
                    BigDecimal unProf = subCost.divide(receivableRmb, 4, BigDecimal.ROUND_HALF_UP);
                    BigDecimal resProf = unProf.multiply(hundred);
                    vo.setProfitMarginDirectCost(resProf);
                }

            }else {
                vo.setProfitMargin(new BigDecimal("0"));
                vo.setProfitMarginDirectCost(new BigDecimal("0"));
            }

            voList.add(vo);
        }
        return voList;
    }

    /**
     * FQ利润统计--分页
     *
     * @param req 查询条件
     * @return FQ利润统计
     */
    public PageInfo<ProfitStatisticsVo> getProfitStatisticsInfo(ProfitStatisticsReq req) {
        //初始化回参对象集合
        List<ProfitStatisticsVo> voList = new ArrayList<>();
        boolean flag=StringUtils.isEmpty(req.getOperationCode()) && StringUtils.isEmpty(req.getSalesmanCode());
        boolean flagDept=StringUtils.isEmpty(req.getDeptOperationCode()) && StringUtils.isEmpty(req.getDeptSalesmanCode());
        if (flag && flagDept) {
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;
        }
        //FQ利润统计
        List<ProfitStatisticsRsp> profitStatisticsInfo = receivePaymentService.getProfitStatisticsInfo(req);
        PageInfo pageInfo = new PageInfo(profitStatisticsInfo);
        if (CollectionUtils.isEmpty(profitStatisticsInfo)) {
            pageInfo.setList(voList);
            return pageInfo;
        }

        pageInfo.setList(getFQInfo(profitStatisticsInfo));
        return pageInfo;
    }


    /**
     * FQ利润统计--导出
     *
     * @return
     */
    public JSONObject collectionStatisticsFQExport(ProfitStatisticsReq req) {
        //FQ利润统计
        List<ProfitStatisticsVo> profitStatisticsInfo = getFQInfo(receivePaymentService.getProfitStatisticsInfo(req));

        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionFQInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(profitStatisticsInfo)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionFQInfoExport(data, profitStatisticsInfo);
        obj.put("data", data);
        return obj;
    }

    private JSONArray getTitleCollectionFQInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("制单公司");
        obj.add("发票号");
        obj.add("发票日期");
        obj.add("外销合同号");
        obj.add("批次");
        obj.add("出运日期");
        obj.add("制单日期");
        obj.add("业务员");
        obj.add("客户名称");
        obj.add("价格术语");
        obj.add("业务模式");
        obj.add("币种");
        obj.add("应收货款");
        obj.add("应收折人民币");
        obj.add("应收货款(USD)");
        obj.add("产品金额小计");
        obj.add("应收结汇费用(RMB)");
        obj.add("应收结汇费用(USD)");
        obj.add("应收费用备注");
        obj.add("实收货款");
        obj.add("实收货款(USD)");
        obj.add("实收折人民币");
        obj.add("未收货款(USD)");
        obj.add("未收折人民币");
        obj.add("银行扣费");
        obj.add("银行扣费折人民币");
        obj.add("认领业务员");
        obj.add("应付货款");
        obj.add("已付货款");
        obj.add("未付货款");
        obj.add("已付费用");
        obj.add("已开票金额");
        obj.add("费用小计(USD)");
        obj.add("费用小计(RMB)");
        obj.add("费用合计(RMB)");
        obj.add("运费");
        obj.add("关税");
        obj.add("美国仓储操作费");
        obj.add("海外仓储费用");
        obj.add("佣金");
        obj.add("货运代理费");
        obj.add("其他相关费用");
        obj.add("预计退税");
        obj.add("实际退税");
        obj.add("预计毛利润（RMB)");
        obj.add("预计毛利润率(不含费用)%");
        obj.add("预计毛利润率(含直接费用)%");

        return obj;
    }


    private void excelCollectionFQInfoExport(JSONArray data, List<ProfitStatisticsVo> list) {
        //应收货款
        BigDecimal invoiceMoney = new BigDecimal("0");
        //应收折人民币
        BigDecimal receivableRmb = new BigDecimal("0");
        //应收货款(USD)
        BigDecimal receivableUsd = new BigDecimal("0");
        //产品金额小计
        BigDecimal productTotalPrice = new BigDecimal("0");
        //应收结汇费用
        BigDecimal costMoney = new BigDecimal("0");
        //实收货款
        BigDecimal collectionAmount = new BigDecimal("0");
        //实收货款(USD)
        BigDecimal collectionAmountUsd = new BigDecimal("0");
        //实收折人民币
        BigDecimal collectionAmountRmb = new BigDecimal("0");
        //未收货款(USD)
        BigDecimal unCollectionAmountUsd = new BigDecimal("0");
        //未收折人民币
        BigDecimal unCollectionAmountRmb = new BigDecimal("0");
        //银行扣费
        BigDecimal foreignBankDeductions = new BigDecimal("0");
        //银行扣费折人民币
        BigDecimal foreignBankDeductionsRmb = new BigDecimal("0");
        //应付货款
        BigDecimal costSubtotalSum = new BigDecimal("0");
        //已付货款
        BigDecimal actuallyAmount = new BigDecimal("0");
        //未付货款
        BigDecimal unActuallyAmount = new BigDecimal("0");
        //已付费用
        BigDecimal applicationAmountCost = new BigDecimal("0");
        //已开票金额
        BigDecimal openedAmount = new BigDecimal("0");
        //费用小计
        BigDecimal applicationAmountSum = new BigDecimal("0");
        //运费
        BigDecimal transferCostSum = new BigDecimal("0");
        //关税
        BigDecimal tariffSum = new BigDecimal("0");
        //美国仓储操作费
        BigDecimal storageOperationFee = new BigDecimal("0");
        //海外仓储费用
        BigDecimal warehouseFee = new BigDecimal("0");
        //佣金
        BigDecimal commission = new BigDecimal("0");
        //货运代理费
        BigDecimal freightForwardingFee = new BigDecimal("0");
        //其他相关费用
        BigDecimal otherFee = new BigDecimal("0");
        //预计退税
        BigDecimal theoreticalTaxRefund = new BigDecimal("0");
        //实际退税
        BigDecimal actualTaxRefund = new BigDecimal("0");
        //预计毛利润（RMB)
        BigDecimal estimatedGrossProfit = new BigDecimal("0");


        int i = 0;
        for (ProfitStatisticsVo vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getCompanyName()));
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceNo()));
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceDate()));
            infoList.add(getNotNullOfStringInfo(vo.getContractNo()));
            infoList.add(getNotNullOfStringInfo(vo.getLetNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCarryDate()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateTime()));
            infoList.add(getNotNullOfStringInfo(vo.getSalesman()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getPriceTerm()));
            infoList.add(getNotNullOfStringInfo(vo.getBusinessModeName()));
            infoList.add(getNotNullOfStringInfo(vo.getMoneyKind()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getInvoiceMoney()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivableRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getReceivableUsd()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductTotalPrice()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCostMoneyOfRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCostMoneyOfUsd()));
            infoList.add(getNotNullOfStringInfo(vo.getCostDesc()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmountUsd()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCollectionAmountRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnCollectionAmountUsd()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnCollectionAmountRmb()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductions()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getForeignBankDeductionsRmb()));
            infoList.add(getNotNullOfStringInfo(vo.getClaimSalesman()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCostSubtotalSum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getActuallyAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnActuallyAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getApplicationAmountCost()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getOpenedAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getApplicationAmountUSD()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getApplicationAmountRMB()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getApplicationAmountSUM()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getTransferCostSum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getTariffSum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getStorageOperationFee()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getWarehouseFee()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCommission()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getFreightForwardingFee()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getOtherFee()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getTheoreticalTaxRefund()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getActualTaxRefund()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getEstimatedGrossProfit()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProfitMargin()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProfitMarginDirectCost()));

            if (StringUtil.isNotEmpty(vo.getInvoiceMoney())) {
                invoiceMoney = invoiceMoney.add(vo.getInvoiceMoney());
            }
            if (StringUtil.isNotEmpty(vo.getReceivableRmb())) {
                receivableRmb = receivableRmb.add(vo.getReceivableRmb());
            }
            if (StringUtil.isNotEmpty(vo.getReceivableUsd())) {
                receivableUsd = receivableUsd.add(vo.getReceivableUsd());
            }

            if (StringUtil.isNotEmpty(vo.getProductTotalPrice())) {
                productTotalPrice = productTotalPrice.add(vo.getProductTotalPrice());
            }

            if (StringUtil.isNotEmpty(vo.getCostMoney())) {
                costMoney = costMoney.add(vo.getCostMoney());
            }
            if (StringUtil.isNotEmpty(vo.getCollectionAmount())) {
                collectionAmount = collectionAmount.add(vo.getCollectionAmount());
            }
            if (StringUtil.isNotEmpty(vo.getCollectionAmountUsd())) {
                collectionAmountUsd = collectionAmountUsd.add(vo.getCollectionAmountUsd());
            }
            if (StringUtil.isNotEmpty(vo.getCollectionAmountRmb())) {
                collectionAmountRmb = collectionAmountRmb.add(vo.getCollectionAmountRmb());
            }
            if (StringUtil.isNotEmpty(vo.getUnCollectionAmountUsd())) {
                unCollectionAmountUsd = unCollectionAmountUsd.add(vo.getUnCollectionAmountUsd());
            }
            if (StringUtil.isNotEmpty(vo.getUnCollectionAmountRmb())) {
                unCollectionAmountRmb = unCollectionAmountRmb.add(vo.getUnCollectionAmountRmb());
            }
            if (StringUtil.isNotEmpty(vo.getForeignBankDeductions())) {
                foreignBankDeductions = foreignBankDeductions.add(vo.getForeignBankDeductions());
            }
            if (StringUtil.isNotEmpty(vo.getForeignBankDeductionsRmb())) {
                foreignBankDeductionsRmb = foreignBankDeductionsRmb.add(vo.getForeignBankDeductionsRmb());
            }
            if (StringUtil.isNotEmpty(vo.getCostSubtotalSum())) {
                costSubtotalSum = costSubtotalSum.add(vo.getCostSubtotalSum());
            }
            if (StringUtil.isNotEmpty(vo.getActuallyAmount())) {
                actuallyAmount = actuallyAmount.add(vo.getActuallyAmount());
            }
            if (StringUtil.isNotEmpty(vo.getUnActuallyAmount())) {
                unActuallyAmount = unActuallyAmount.add(vo.getUnActuallyAmount());
            }
            if (StringUtil.isNotEmpty(vo.getApplicationAmountCost())) {
                applicationAmountCost = applicationAmountCost.add(vo.getApplicationAmountCost());
            }
            if (StringUtil.isNotEmpty(vo.getOpenedAmount())) {
                openedAmount = openedAmount.add(vo.getOpenedAmount());
            }
            if (StringUtil.isNotEmpty(vo.getApplicationAmountRMB())) {
                applicationAmountSum = applicationAmountSum.add(vo.getApplicationAmountRMB());
            }
            if (StringUtil.isNotEmpty(vo.getTransferCostSum())) {
                transferCostSum = transferCostSum.add(vo.getTransferCostSum());
            }
            if (StringUtil.isNotEmpty(vo.getTariffSum())) {
                tariffSum = tariffSum.add(vo.getTariffSum());
            }
            if (StringUtil.isNotEmpty(vo.getStorageOperationFee())) {
                storageOperationFee = storageOperationFee.add(vo.getStorageOperationFee());
            }
            if (StringUtil.isNotEmpty(vo.getWarehouseFee())) {
                warehouseFee = warehouseFee.add(vo.getWarehouseFee());
            }
            if (StringUtil.isNotEmpty(vo.getCommission())) {
                commission = commission.add(vo.getCommission());
            }
            if (StringUtil.isNotEmpty(vo.getFreightForwardingFee())) {
                freightForwardingFee = freightForwardingFee.add(vo.getFreightForwardingFee());
            }
            if (StringUtil.isNotEmpty(vo.getOtherFee())) {
                otherFee = otherFee.add(vo.getOtherFee());
            }
            if (StringUtil.isNotEmpty(vo.getTheoreticalTaxRefund())) {
                theoreticalTaxRefund = theoreticalTaxRefund.add(vo.getTheoreticalTaxRefund());
            }
            if (StringUtil.isNotEmpty(vo.getActualTaxRefund())) {
                actualTaxRefund = actualTaxRefund.add(vo.getActualTaxRefund());
            }
            if (StringUtil.isNotEmpty(vo.getEstimatedGrossProfit())) {
                estimatedGrossProfit = estimatedGrossProfit.add(vo.getEstimatedGrossProfit());
            }


            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(invoiceMoney);
        titleList.add(receivableRmb);
        titleList.add(receivableUsd);
        titleList.add(productTotalPrice);
        titleList.add(costMoney);
        titleList.add("");
        titleList.add(collectionAmount);
        titleList.add(collectionAmountUsd);
        titleList.add(collectionAmountRmb);
        titleList.add(foreignBankDeductions);
        titleList.add(foreignBankDeductionsRmb);
        titleList.add("");
        titleList.add(costSubtotalSum);
        titleList.add(actuallyAmount);
        titleList.add(unActuallyAmount);
        titleList.add(applicationAmountCost);
        titleList.add(openedAmount);
        titleList.add(applicationAmountSum);
        titleList.add(transferCostSum);
        titleList.add(tariffSum);
        titleList.add(storageOperationFee);
        titleList.add(warehouseFee);
        titleList.add(commission);
        titleList.add(freightForwardingFee);
        titleList.add(otherFee);
        titleList.add(theoreticalTaxRefund);
        titleList.add(actualTaxRefund);
        titleList.add(estimatedGrossProfit);

        data.add(titleList);
    }


    /**
     * 根据发票编号获取收款主表id(多个id以英文逗号隔开)
     *
     * @param billNo 发票编号
     * @return 收款主表id(多个id以英文逗号隔开)
     */
    public String getReceivePaymentId(String billNo) {
        if (StringUtils.isEmpty(billNo)) {
            return "";
        }
        String ids = receivePaymentService.getReceivePaymentId(billNo);
        if (StringUtils.isEmpty(ids)) {
            return "";
        }
        return ids;
    }

    /**
     * 生成最新收款单号
     *
     * @return 新收款单号
     */
    public String getReceivePaymentBillNo() {
        //初始化查询对象
        ReceivePaymentListReq req = new ReceivePaymentListReq();
        //当前年月日
        String currentDate = DateUtils.format(new Date());
        //创建时间(起止)
        String createDateStart = currentDate + " 00:00:00";
        req.setCreateDateStart(createDateStart);
        //创建时间(截至)
        String createDateEnd = currentDate + " 23:59:59";
        req.setCreateDateEnd(createDateEnd);
        List<ReceivePaymentEntity> receivePayment = receivePaymentService.getReceivePaymentBillNoByQuery(req);
        if (CollectionUtils.isEmpty(receivePayment)) {
            //当天未创建单据，单号从001开始
            return "RTCO" + currentDate.replace("-", "") + "001";
        }
        //当天已创建单号,获取最后创建的单号
        String billNo = receivePayment.get(0).getBillNo();
        //截取最后三位序列号
        String serialNumber = billNo.substring(billNo.length() - 3);
        //数据转换
        BigDecimal formatBigDecimal = new BigDecimal(serialNumber);
        //生成新的序列号(序列号自增一位)
        String newSerialNumber = formatBigDecimal.add(new BigDecimal("1")).toString();
        if (1 == newSerialNumber.length()) {
            newSerialNumber = "00" + newSerialNumber;
        } else if (2 == newSerialNumber.length()) {
            newSerialNumber = "0" + newSerialNumber;
        }
        //生成最新报价单号
        return "RTCO" + currentDate.replace("-", "") + newSerialNumber;
    }

    /**
     * 产品统计-分页
     *
     * @param req 查询条件
     * @return 产品统计
     */
    public PageInfo<ProductStatisticsRsp> getProductStatisticsByPage(ProductStatisticsReq req) {
        List<ProductStatisticsRsp> productStatisticsInfo = receivePaymentService.getProductStatisticsInfo(req);
        //初始化回参对象集合
        List<ProductStatisticsRsp> voList = new ArrayList<>();
        if (CollectionUtils.isEmpty(productStatisticsInfo)) {
            PageInfo pageInfo = new PageInfo();
            pageInfo.setList(voList);
            return pageInfo;
        }
        //获取分页信息
        PageInfo pageInfo = new PageInfo(productStatisticsInfo);
        return pageInfo;
    }

    /**
     * 产品统计-导出
     * @param req
     * @return
     */
    public JSONObject productStatisticsExport(ProductStatisticsReq req){
        List<ProductStatisticsRsp> productStatisticsInfo = receivePaymentService.getProductStatisticsInfo(req);

        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleProductCollectionInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(productStatisticsInfo)) {
            obj.put("data", data);
            return obj;
        }
        excelProductCollectionSixInfoExport(data, productStatisticsInfo);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleProductCollectionInfo() {
        JSONArray obj = new JSONArray();
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("中文描述");
        obj.add("英文描述");
        obj.add("中文名称");
        obj.add("英文名称");
        obj.add("采购币种");
        obj.add("含税出厂价");
        obj.add("未税出厂价");
        obj.add("配件编码");
        return obj;
    }
    private void excelProductCollectionSixInfoExport(JSONArray data, List<ProductStatisticsRsp> list) {
        for (ProductStatisticsRsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationCode()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCdesc()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEdesc()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCname()));
            infoList.add(getNotNullOfStringInfo(vo.getProductEname()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseCurrency()));
            infoList.add(getNotNullOfStringInfo(vo.getTaxIncludedCost()));
            infoList.add(getNotNullOfStringInfo(vo.getUntaxedCost()));
            infoList.add(getNotNullOfStringInfo(vo.getPartsCode()));
            data.add(infoList);
        }

    }




    /**
     * 产品出货详情统计--集合
     * @param req
     * @return
     */
    private List<CollectionStatistics6Rsp> getCollectionStatistics6List(CollectionStatistics6Req req){
        List<CollectionStatistics6Rsp> collectionStatistics6RspList=receivePaymentService.getCollectionStatistics6List(req);
        for (CollectionStatistics6Rsp p:collectionStatistics6RspList){
            p.setSigningDateStr(DateUtils.format(p.getSigningDate(),DateUtils.DATE_PATTERN));
            p.setBusinessDeliveryDateStr(DateUtils.format(p.getBusinessDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setDeliveryDateStr(DateUtils.format(p.getSigningDate(),DateUtils.DATE_PATTERN));
            p.setFeedbackDeliveryDateStr(DateUtils.format(p.getFeedbackDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setActualDeliveryDateStr(DateUtils.format(p.getActualDeliveryDate(),DateUtils.DATE_PATTERN));
            p.setCreateTimeStr(DateUtils.format(p.getActualDeliveryDate(),DateUtils.DATE_PATTERN));
        }
        return collectionStatistics6RspList;
    }
    /**
     * 产品出货详情统计--分页
     * @param req
     * @return
     */
    public PageInfo<CollectionStatistics6Rsp> collectionStatistics6ListByPage(CollectionStatistics6Req req){
        List<CollectionStatistics6Rsp> profitStatisticsInfo = getCollectionStatistics6List(req);
        PageInfo pageInfo=new PageInfo(profitStatisticsInfo);
        return pageInfo;
    }

    /**
     * 产品出货详情统计--导出
     *
     * @return
     */
    public JSONObject collectionStatisticsSixExport(CollectionStatistics6Req req) {
        List<CollectionStatistics6Rsp> profitStatisticsInfo = getCollectionStatistics6List(req);

        JSONObject obj = new JSONObject();
        //获取excel的title信息
        JSONArray titleList = getTitleCollectionSixInfo();
        JSONArray data = new JSONArray();
        data.add(titleList);
        if (CollectionUtils.isEmpty(profitStatisticsInfo)) {
            obj.put("data", data);
            return obj;
        }
        excelCollectionSixInfoExport(data, profitStatisticsInfo);
        obj.put("data", data);
        return obj;
    }
    private JSONArray getTitleCollectionSixInfo() {
        JSONArray obj = new JSONArray();
        obj.add("序号");
        obj.add("外销合同号");
        obj.add("客户名称");
        obj.add("客户编码");
        obj.add("客户来源");
        obj.add("产品编码");
        obj.add("规格编码");
        obj.add("签约日期");
        obj.add("业务要求交货日期");
        obj.add("单价");
        obj.add("外销金额小计");
        obj.add("采购日期");
        obj.add("采购单号");
        obj.add("供应商名称");
        obj.add("外销数量");
        obj.add("数量");
        obj.add("产品单价");
        obj.add("产品费用");
        obj.add("采购成本");
        obj.add("产品单价小计");
        obj.add("采购成本小计");
        obj.add("要求交货日期");
        obj.add("供应商反馈交期");
        obj.add("实际交期");
        obj.add("出运计划号");
        obj.add("出运计划数量");
        obj.add("计划剩余数量");
        obj.add("出运发票号");
        obj.add("出运明细数量");
        obj.add("出运明细剩余数量");
        obj.add("结汇发票号");
        obj.add("结汇数量");
        obj.add("结汇剩余数量");

        return obj;
    }

    private void excelCollectionSixInfoExport(JSONArray data, List<CollectionStatistics6Rsp> list) {
        //外销金额小计
        BigDecimal contractMoneySubtotal = new BigDecimal("0");
        //外销数量
        BigDecimal contractNum = new BigDecimal("0");
        //数量
        BigDecimal num = new BigDecimal("0");
        //产品单价
        BigDecimal productPrice = new BigDecimal("0");
        //产品费用
        BigDecimal productCost = new BigDecimal("0");
        //采购成本
        BigDecimal purchaseCost = new BigDecimal("0");
        //产品单价小计
        BigDecimal productPriceSubtotal = new BigDecimal("0");
        //采购成本小计
        BigDecimal purchaseCostSubtotal = new BigDecimal("0");
        //出运计划数量
        BigDecimal planAmount = new BigDecimal("0");
        //计划剩余数量
        BigDecimal lastAmountOfPlan = new BigDecimal("0");
        //出运明细数量
        BigDecimal carryDetailNum = new BigDecimal("0");
        //出运明细剩余数量
        BigDecimal lastAmountOfDetail = new BigDecimal("0");
        //结汇数量
        BigDecimal billExchangeInfoNum = new BigDecimal("0");
        //结汇剩余数量
        BigDecimal lastAmountOfBillExchange = new BigDecimal("0");


        int i = 0;
        for (CollectionStatistics6Rsp vo : list) {
            JSONArray infoList = new JSONArray();
            infoList.add(++i);
            infoList.add(getNotNullOfStringInfo(vo.getBillNo()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerName()));
            infoList.add(getNotNullOfStringInfo(vo.getCustomerCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSourceOfCustomers()));
            infoList.add(getNotNullOfStringInfo(vo.getProductCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSpecificationCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSigningDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getBusinessDeliveryDateStr()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getUnitPrice()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getContractMoneySubtotal()));
            infoList.add(getNotNullOfStringInfo(vo.getCreateTimeStr()));
            infoList.add(getNotNullOfStringInfo(vo.getPurchaseOrderCode()));
            infoList.add(getNotNullOfStringInfo(vo.getSupplierName()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getContractNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductPrice()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductCost()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getPurchaseCost()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getProductPriceSubtotal()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getPurchaseCostSubtotal()));
            infoList.add(getNotNullOfStringInfo(vo.getDeliveryDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getFeedbackDeliveryDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getActualDeliveryDateStr()));
            infoList.add(getNotNullOfStringInfo(vo.getCarryPlanNo()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getPlanAmount()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getLastAmountOfPlan()));
            infoList.add(getNotNullOfStringInfo(vo.getCarryInvoiceNo()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getCarryDetailNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getLastAmountOfDetail()));
            infoList.add(getNotNullOfStringInfo(vo.getInvoiceNo()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getBillExchangeInfoNum()));
            infoList.add(getNotNullOfBigDecimalInfo(vo.getLastAmountOfBillExchange()));

            if (StringUtil.isNotEmpty(vo.getContractMoneySubtotal())) {
                contractMoneySubtotal = contractMoneySubtotal.add(vo.getContractMoneySubtotal());
            }
            if (StringUtil.isNotEmpty(vo.getContractNum())) {
                contractNum = contractNum.add(vo.getContractNum());
            }
            if (StringUtil.isNotEmpty(vo.getNum())) {
                num = num.add(vo.getNum());
            }

            if (StringUtil.isNotEmpty(vo.getProductPrice())) {
                productPrice = productPrice.add(vo.getProductPrice());
            }

            if (StringUtil.isNotEmpty(vo.getProductCost())) {
                productCost = productCost.add(vo.getProductCost());
            }
            if (StringUtil.isNotEmpty(vo.getPurchaseCost())) {
                purchaseCost = purchaseCost.add(vo.getPurchaseCost());
            }
            if (StringUtil.isNotEmpty(vo.getProductPriceSubtotal())) {
                productPriceSubtotal = productPriceSubtotal.add(vo.getProductPriceSubtotal());
            }
            if (StringUtil.isNotEmpty(vo.getPurchaseCostSubtotal())) {
                purchaseCostSubtotal = purchaseCostSubtotal.add(vo.getPurchaseCostSubtotal());
            }
            if (StringUtil.isNotEmpty(vo.getPlanAmount())) {
                planAmount = planAmount.add(vo.getPlanAmount());
            }
            if (StringUtil.isNotEmpty(vo.getLastAmountOfPlan())) {
                lastAmountOfPlan = lastAmountOfPlan.add(vo.getLastAmountOfPlan());
            }
            if (StringUtil.isNotEmpty(vo.getCarryDetailNum())) {
                carryDetailNum = carryDetailNum.add(vo.getCarryDetailNum());
            }
            if (StringUtil.isNotEmpty(vo.getLastAmountOfDetail())) {
                lastAmountOfDetail = lastAmountOfDetail.add(vo.getLastAmountOfDetail());
            }
            if (StringUtil.isNotEmpty(vo.getBillExchangeInfoNum())) {
                billExchangeInfoNum = billExchangeInfoNum.add(vo.getBillExchangeInfoNum());
            }
            if (StringUtil.isNotEmpty(vo.getLastAmountOfBillExchange())) {
                lastAmountOfBillExchange = lastAmountOfBillExchange.add(vo.getLastAmountOfBillExchange());
            }


            data.add(infoList);
        }
        //合计
        JSONArray titleList = new JSONArray();
        titleList.add("合计");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(contractMoneySubtotal);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(contractNum);
        titleList.add(num);
        titleList.add(productPrice);
        titleList.add(productCost);
        titleList.add(purchaseCost);
        titleList.add(productPriceSubtotal);
        titleList.add(purchaseCostSubtotal);
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add("");
        titleList.add(planAmount);
        titleList.add(lastAmountOfPlan);
        titleList.add("");
        titleList.add(carryDetailNum);
        titleList.add(lastAmountOfDetail);
        titleList.add("");
        titleList.add(billExchangeInfoNum);
        titleList.add(lastAmountOfBillExchange);

        data.add(titleList);
    }


    /**
     * 通过外销合同号获取收款明细信息
     *
     * @param contractNo 外销合同号
     * @return 收款明细信息
     */
    public List<ReceivePaymentDetailEntity> getReceivePaymentByContractNo(String contractNo) {
        if (StringUtils.isEmpty(contractNo)) {
            return new ArrayList<>();
        }
        //设置查询参数
        ReceivePaymentDetailEntity req = new ReceivePaymentDetailEntity();
        //外销合同号
        req.setContractNo(contractNo);
        //数据有效
        req.setValid(DataIsValidEnum.VALID.getId());
        //查询结果
        List<ReceivePaymentDetailEntity> detailList = receivePaymentDetailService.queryAll(req);
        return detailList;
    }

    /**
     * 获取订单详情
     * @param req 订单详情入参查询
     * @return 订单详情
     */
    public PageInfo<OrderDetailVo> getOrderDetailByPage(OrderDetailReq req){
        if (StringUtils.isNotEmpty(req.getBillNo())) {
            //单号去除前后空格
            req.setBillNo(req.getBillNo().trim());
        }
        if (StringUtils.isNotEmpty(req.getCustomerName())) {
            //客户名称去除前后空格
            req.setBillNo(req.getCustomerName().trim());
        }
        List<OrderDetailRsp> orderDetails = receivePaymentService.getOrderDetail(req);
        PageInfo pageInfo = new PageInfo(orderDetails);
        if (CollectionUtils.isEmpty(orderDetails)) {
            pageInfo.setList(orderDetails);
            return pageInfo;
        }
        List<OrderDetailVo> voList = new ArrayList<>();
        for (OrderDetailRsp orderDetail : orderDetails) {
            OrderDetailVo vo = new OrderDetailVo();
            //对象赋值
            BeanUtils.copyProperties(orderDetail, vo);
            //签约日期
            if (null != orderDetail.getSigningDate()) {
                vo.setSigningDate(DateUtils.format(orderDetail.getSigningDate()));
            }
            //最后一次水单认领日期
            if (null != orderDetail.getReceivePaymentCollectionClaimDate()) {
                vo.setReceivePaymentCollectionClaimDate(DateUtils.format(orderDetail.getReceivePaymentCollectionClaimDate()));
            }
            //最后一次结汇日期
            if (null != orderDetail.getInvoiceDate()) {
                vo.setInvoiceDate(DateUtils.format(orderDetail.getInvoiceDate()));
            }
            //外销总额
            BigDecimal totalContractAmount = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getTotalContractAmount())) {
                totalContractAmount = orderDetail.getTotalContractAmount();
            }
            //美金汇率
            BigDecimal usdRate = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getUsdRate())) {
                usdRate = orderDetail.getUsdRate();
            }
            //rmb汇率
            BigDecimal rmbRate = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getRmbRate())) {
                rmbRate = orderDetail.getRmbRate();
            }
            //结汇产品总额
            BigDecimal moneySubtotal = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getMoneySubtotal())) {
                moneySubtotal = orderDetail.getMoneySubtotal();
            }
            //结汇费用
            BigDecimal costMoney = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getCostMoney())) {
                costMoney = orderDetail.getCostMoney();
            }
            //外销总额(RMB)
            BigDecimal totalContractAmountRMB = new BigDecimal("0");
            //结汇总额(需转换币种) = 结汇产品总额 + 结汇费用
            BigDecimal tempMoneySubtotal = moneySubtotal.add(costMoney);
            //结汇总额(RMB)
            BigDecimal moneySubtotalRMB = new BigDecimal("0");
            if (orderDetail.getCurrency().equals("人民币") || orderDetail.getCurrency().equals("RMB")) {
                if (usdRate.compareTo(BigDecimal.valueOf(1)) == 1) {
                    vo.setTotalContractAmountUSD(totalContractAmount.divide(usdRate, 2, BigDecimal.ROUND_HALF_UP));
                } else {
                    vo.setTotalContractAmountUSD(totalContractAmount.multiply(usdRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                }
                //外销总额(RMB)
                totalContractAmountRMB = totalContractAmount;
                //结汇总额(RMB)
                moneySubtotalRMB = tempMoneySubtotal;
            } else {
                vo.setTotalContractAmountUSD((totalContractAmount.multiply(usdRate)).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP));
                //外销总额(RMB)
                totalContractAmountRMB = totalContractAmount.multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP);
                //结汇总额(RMB)
                moneySubtotalRMB = tempMoneySubtotal.multiply(usdRate).multiply(rmbRate).divide(BigDecimal.valueOf(1), 2, BigDecimal.ROUND_HALF_UP);
            }
            //外销总额(RMB)
            vo.setTotalContractAmountRMB(totalContractAmountRMB);
            //结汇总额(RMB)
            vo.setMoneySubtotalRMB(moneySubtotalRMB);

            //收款金额
            BigDecimal receivePaymentCollectionAmountSum = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getReceivePaymentCollectionAmountSum())) {
                receivePaymentCollectionAmountSum = orderDetail.getReceivePaymentCollectionAmountSum();
            }
            //未收款金额(结汇) = 结汇产品总额 + 结汇费用 - 收款金额
            BigDecimal unReceivePaymentBillExchangeSum = moneySubtotal.add(costMoney).subtract(receivePaymentCollectionAmountSum);
            vo.setUnReceivePaymentBillExchangeSum(unReceivePaymentBillExchangeSum);

            //外销数量
            BigDecimal productNum = new BigDecimal("0");
            if (StringUtil.isNotEmpty(orderDetail.getProductNum())) {
                productNum = orderDetail.getProductNum();
            }
            //采购剩余数量 = 外销数量 - 采购数量
            BigDecimal purchaseLastAmount = productNum.subtract(orderDetail.getPurchaseAmountSum());
            vo.setPurchaseLastAmount(purchaseLastAmount);

            //出运剩余数量 = 外销数量 - 出运数量
            BigDecimal carryLastAmount = productNum.subtract(orderDetail.getCarryProductNum());
            vo.setCarryLastAmount(carryLastAmount);

            //结汇剩余数量 = 外销数量 - 结汇数量
            BigDecimal billExchangeLastAmount = productNum.subtract(orderDetail.getGoodsNum());
            vo.setBillExchangeLastAmount(billExchangeLastAmount);

            //边际毛利率(外销) = (销售订单总额RMB - 采购成本 - 直接费用)/销售订单总额RMB*100%
            BigDecimal marginalGrossMarginContract = new BigDecimal("0");
            if (totalContractAmountRMB.compareTo(BigDecimal.ZERO) == 1) {
                BigDecimal tmpMarginalGrossMarginContract = totalContractAmountRMB.subtract(orderDetail.getPurchasePrdtAndPartsSum()).subtract(orderDetail.getApplicationAmount());
                marginalGrossMarginContract = tmpMarginalGrossMarginContract.divide(totalContractAmountRMB, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            }
            vo.setMarginalGrossMarginContract(marginalGrossMarginContract + "%");

            //边际毛利率(结汇) = (结汇总额RMB - 采购成本 - 直接费用)/结汇总额RMB*100%
            BigDecimal marginalGrossMarginExchange = new BigDecimal("0");
            if(moneySubtotalRMB.compareTo(BigDecimal.ZERO) == 1){
                BigDecimal tmpMarginalGrossMarginExchange = moneySubtotalRMB.subtract(orderDetail.getPurchasePrdtAndPartsSum()).subtract(orderDetail.getApplicationAmount());
                marginalGrossMarginExchange = tmpMarginalGrossMarginExchange.divide(moneySubtotalRMB, 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
            }
            vo.setMarginalGrossMarginExchange(marginalGrossMarginExchange + "%");

            voList.add(vo);
        }

        pageInfo.setList(voList);
        return pageInfo;
    }

    /**
     * 根据外销合同号查询收款明细中认领的合同，有则返回true 无返回false
     * @param contractCode
     * @return
     */
    public boolean isLinkedCollections(String contractCode){
        ReceivePaymentDetailEntity receivePaymentDetail=new ReceivePaymentDetailEntity();
        receivePaymentDetail.setValid(1);
        receivePaymentDetail.setContractNo(contractCode);
        List<ReceivePaymentDetailEntity> entityList = receivePaymentDetailService.queryAll(receivePaymentDetail);
        if (CollectionUtils.isEmpty(entityList)){
            return false;
        }else{
            return true;
        }
    }
    /**
     * 返回收汇金额 总计
     * @param contractCode
     * @return
     */
    public Double getLinkedCollectionsAmount(String contractCode){
        ReceivePaymentDetailEntity receivePaymentDetail=new ReceivePaymentDetailEntity();
        receivePaymentDetail.setValid(1);
        receivePaymentDetail.setContractNo(contractCode);
        List<ReceivePaymentDetailEntity> entityList = receivePaymentDetailService.queryAll(receivePaymentDetail);
        if (CollectionUtils.isEmpty(entityList)){
            return 0d;
        }else{
            BigDecimal result=new BigDecimal(0);
            for (ReceivePaymentDetailEntity p: entityList) {
                result=result.add(p.getCollectionAmount());
            }
            return result.doubleValue();
        }
    }
}
